/**
 * 配置信息
 * @author yqling by 2022.05
 */

 (function (window, undefined) {
  window.config = {};

  // 公司测试环境
  config.BASE_URL = ""; // 地址前缀
  // config.NET_ATTR = "http://132.232.138.176:9853"; // 接口前缀
  // config.IMG_ATTR = "http://132.232.138.176:9850/datafile"; // 静态资源前缀

  // 甘肃测试环境
  config.BASE_URL = "http://117.157.65.52:16802"; // 地址前缀
  config.NET_ATTR = "http://117.157.65.52:16800"; // 接口前缀
  config.IMG_ATTR = "http://117.157.65.52:16802/datafile"; // 静态资源前缀

  // 甘肃正式环境-ip
  // config.BASE_URL = ""; // 地址前缀
  // config.NET_ATTR = "http://117.157.65.52:8302"; // 接口前缀
  // config.IMG_ATTR = "http://117.157.65.52:8301/datafile"; // 静态资源前缀

  // 甘肃灾备环境
  // config.BASE_URL = ""; // 地址前缀
  // config.NET_ATTR = "http://117.157.241.24:8302"; // 接口前缀
  // config.IMG_ATTR = "http://117.157.241.24:8301/datafile"; // 静态资源前缀

  // 甘肃正式环境-域名
  // config.BASE_URL = ""; // 地址前缀
  // config.NET_ATTR = "http://hy.iptv.gstv.com.cn:8302"; // 接口前缀
  // config.IMG_ATTR = "http://hy.iptv.gstv.com.cn:8301/datafile"; // 静态资源前缀

  // 甘肃正式环境-WAF域名
  // config.BASE_URL = ""; // 地址前缀
  // config.NET_ATTR = "http://hyapi.iptv.gstv.com.cn:8888"; // 接口前缀
  // config.IMG_ATTR = "http://hyweb.iptv.gstv.com.cn:8888/datafile"; // 静态资源前缀

  // config.NET_ATTR = "http://117.157.65.52:8302";
  // config.IMG_ATTR = "http://117.157.65.52:8301/datafile";

  // 默认图片
  config.IMG_DEFAULT = "../img/default.jpg";
  config.IMG_LOADING = "../img/default.jpg";

  // 根栏目编码
  // config.CODE_ROOT = "11654662343554303";
  // 首页栏目编码
  // config.CODE_INDEX = "e8727bde053e41168242ce21a173fe2c";

  /*-----------------用户信息start-----------------------*/

  config.DEFAULT_STB_IP = "175.9.47.171";
  config.DEFAULT_USER_ID = "HNTV01CS00046871";
  config.DEFAULT_TOKEN = "v3t3584mrag5op2srfa6m4mr8n";
  config.DEFAULT_STB_ID = "";
  config.DEFAULT_MAC = "C0:8F:20:8B:1C:3C";
  config.DEFAULT_STB_TYPE = "H10g-12";
  config.DEFAULT_USER_GROUP = "";
  config.DEFAULT_AREA_CODE = "";
  config.DEFAULT_COUNTRY_CODE = "";
  config.DEFAULT_CITY_CODE = "";

  /** 湖南有线蜗牛酒店正式环境-软终端有线测试账号 */
  //账号: HNTS01CS00001328
  //Mac: 9c:b2:b2:1e:23:01

  /** 湖南有线蜗牛酒店正式环境-测试账号 */
  //账号: HNTV01CS00046871
  //Mac: C0:8F:20:8B:1C:3C

  /** 甘肃飞视测试环境-测试账号 */
  //账号: 005801FF0001007006BA60D21C61516F
  //Mac: 005801FF0001007006BA60D21C61516F

  /** 公司测试环境用户-一曼酒店 */
  //账号: HNTV01CS00043554
  //Mac: A0:67:20:0A:6F:3D

  /** 公司测试环境用户-尊享版-楚天科技 */
  //账号: HNTV01CS00072157
  //Mac: 7C:52:59:83:BE:63

  /** 通用EPG模拟终端账号 */
  //账号: TEST00000001
  //Mac: 00:00:00:00:00:00

  /*-----------------用户信息end-----------------------*/

  /*-----------------播放start-----------------------*/

  config.PLAYER_MODE = "default"; //播放器模式 1.vlc：vlc播放器 2.exo：exo播放器 3.default：原生默认 4.h5：h5模式播放器

  /*-----------------播放end-----------------------*/

  /*-----------------第三方应用启动默认参数start-----------------------*/

  config.DEFAULT_START_PACKAGE_NAME = "com.hunancatv.wnst"; //默认包名
  config.DEFAULT_START_CLASS_NAME = "com.hunancatv.loading.LoadingActivity"; //默认类名
  config.DEFAULT_START_EXTRA_KEY = ""; //默认额外参数extra的key
  config.DEFAULT_START_EXTRA_DATA = ""; //默认额外参数extra的值
  config.DEFAULT_START_URI = ""; //默认uri
  config.DEFAULT_START_APP_ID = "29309731"; //默认appId

  /*-----------------第三方应用启动默认参数-----------------------*/

  /*-----------------根据访问链接判断接口地址start-----------------------*/
  // var $hostName = window.location.hostname;
  // if ($hostName != "127.0.0.1") {
  //   // 接口前缀
  //   config.NET_ATTR = "http://" + $hostName + ":8302";
  //   // 图片前缀
  //   config.IMG_ATTR = "http://" + $hostName + ":8301/datafile";
  // }
  // if ($hostName == "hyweb.iptv.gstv.com.cn") {
  //   // 接口前缀
  //   config.NET_ATTR = "http://hyapi.iptv.gstv.com.cn:8888";
  //   // 图片前缀
  //   config.IMG_ATTR = "http://" + $hostName + ":8888/datafile";
  // }
  /*-----------------根据访问链接判断接口地址end-----------------------*/
})(window);

/**
 * 工具类库
 * @author yqling by 2022.05
 */

/**
 * 页面跳转的方法，在安卓模式下不打开窗口，在本窗口跳转页面
 * @param {string} url 跳转地址
 */
function loadUrl(url, saveParam, focus, clearHis) {
  if (!focus) {
    Wrapper.saveFocus(saveParam);
  }
  if (url.indexOf("http://") == -1 && url.indexOf("../") == -1) {
    url = config.BASE_URL + url;
  }
  if (typeof nativeClient != "undefined") {
    nativeClient.loadUrl(url);
    if (clearHis) {
      nativeClient.clearLastHistory();
    }
  } else {
    window.location.href = url;
  }
}

/**
 * 清除webview浏览记录
 */
function clearHistory() {
  if (typeof nativeClient != "undefined") {
    nativeClient.clearHistory();
  }
}

/**
 * APK 退出APP
 */
function exitApp() {
  if (typeof nativeClient != "undefined") {
    nativeClient.exit();
  } else {
    alertMsg("网页版不能退出APK");
  }
}

/**
 * APK模式 返回句柄
 */
function goBack(enforce) {
  console.log("goBack");
  Wrapper.goBack(enforce);
}

/**
 * EPG模式 返回句柄
 */
function acceptBack() {
  Wrapper.goBack();
}

// __________________________________________________________________

/**
 * 常规抖动动画
 * @param {*} dom 节点
 * @param {*} dir 方向
 * eg: setShakeAnimation(document.body)
 */
function setShakeAnimation(dom, dir) {
  if (!window["flag_isAnima_shake"]) {
    window["flag_isAnima_shake"] = true;
    var dir_horizontal = dir == 1 || dir == 3;
    var dir_flag = dir == 0 || dir == 1;
    var _before_transform = window.getComputedStyle(dom, null).webkitTransform;
    if (_before_transform == "none") {
      _before_transform = "";
    }
    var options = {
      swing: [20, -20, 20, -10, 10, -10, 0], // 摆幅组
      power: 5, // 抛动力
    };
    var onceTime = options.swing[0] * options.power;
    var _t = 0;
    var _len_swing = options.swing.length;
    var _timer = setInterval(function () {
      if (++_t < _len_swing) {
        var nowSwing = options.swing[_t] * (dir_flag ? 1 : -1);
        onceTime = Math.abs(nowSwing) * 5;
        if (onceTime == 0) {
          onceTime = 10;
        }
        // console.log(nowSwing, onceTime);
        dom.style.webkitTransition = dom.style.transition = "all " + onceTime + "ms linear";
        dom.style.webkitTransform = dom.style.transform = _before_transform + " translate" + (dir_horizontal ? "X" : "Y") + "(" + nowSwing + "px)";
      } else {
        dom.style.webkitTransform = dom.style.transform = "";
        dom.style.webkitTransition = dom.style.transition = "";
        clearInterval(_timer);
        _timer = null;
        window["flag_isAnima_shake"] = false;
      }
    }, onceTime);
  }
}

/**
 * 设置修复正确的屏幕位置-直接模式
 * @param {*} dom
 * @param {*} options
 * @param {*} callback
 */
function setScreenPosition(dom, options, callback) {
  if (!dom) {
    return false;
  }
  //默认配置
  if (options == undefined) {
    options = {};
  }
  //默认前置位移
  if (options.start_offset == undefined) {
    options.start_offset = 0;
  }
  //默认滚动条dom
  if (options.scrollDom == undefined) {
    options.scrollDom = dom.parentNode;
  }
  //默认视图dom
  if (options.viewDom == undefined) {
    options.viewDom = options.scrollDom.parentNode;
  }
  //
  if (options.viewPosition == undefined) {
    options.viewPosition = 0;
  }
  //纵向检测
  // 视图高度
  var view_height = options.viewDom.offsetHeight;
  // 自身高度
  var self_height = dom.offsetHeight;
  // 自身顶部相对于视图顶部的距离差
  var self_offsetTop = getAbsPointClac(dom, options.scrollDom).y;
  if (options.viewOffset === undefined) {
    var sc_height = -(self_offsetTop - view_height / 2 + self_height / 2) - options.viewPosition;
    options.scrollDom.style.webkitTransform = "translateY(" + sc_height + "px)";
  } else {
    options.scrollDom.style.webkitTransform = "translateY(" + (options.viewOffset + options.start_offset) + "px)";
  }
  callback && callback();
}

/**
 * 测试弹窗方法，安卓模式下调用安卓toast方法
 * @param {string} msg 弹窗消息
 */
function deBugMsg(msg) {
  if (typeof nativeClient != "undefined") {
    nativeClient.toast(msg);
  } else {
    alertMsg(msg, false, true);
  }
}

/**
 * 公共弹窗具体实现逻辑
 * @param {*} type 弹窗alert 吐司toast
 * @param {*} msg 消息文本
 * @param {*} alwaysShow 保持前端显示
 * @param {*} reset 初始化
 */
var commonMsg = function (type, msg, alwaysShow, reset) {
  if (window.commonMsgTimer === undefined) {
    window.commonMsgTimer = {};
  }
  if (window.commonMsgTimer[type] !== null) {
    window.clearTimeout(window.commonMsgTimer[type]);
    window.commonMsgTimer[type] = null;
  }
  var _name = "dia-" + type;
  var _dom = document.getElementById(_name);
  if (!_dom) {
    _dom = document.createElement("div");
    _dom.id = _dom.className = _name;
  } else {
    _dom.style.opacity = "1";
  }
  if (reset) {
    _dom.innerHTML = msg;
  } else {
    _dom.innerHTML += msg;
  }
  document.body.appendChild(_dom);
  if (!alwaysShow) {
    if (window.commonMsgTimer[type] != null) {
      window.clearTimeout(window.commonMsgTimer[type]);
      window.commonMsgTimer[type] = null;
    }
    window.commonMsgTimer[type] = window.setTimeout(function () {
      _dom.style.opacity = "0";
    }, 2000);
  }
};

/**
 * EPG弹窗
 * @param {string} msg
 * @param {*} alwaysShow
 * @param {*} reset
 */
var alertMsg = function (msg, alwaysShow, reset) {
  commonMsg("alert", msg, alwaysShow, reset);
};

/**
 * EPG弹窗 开发者模式实现
 * @param {*} msg
 * @param {*} alwaysShow
 * @param {*} reset
 */
var alertDev = function (msg, alwaysShow, reset) {
  if (DEVELOPER_MODE) {
    alertMsg(msg, alwaysShow, reset);
  }
};

/**
 * EPG吐司
 * @param {*} msg
 * @param {*} alwaysShow
 * @param {*} reset
 */
var toastMsg = function (msg, alwaysShow, reset) {
  commonMsg("toast", msg, alwaysShow, reset);
};

/**
 * 获取软件(epg)版本号
 * @returns
 */
function getEpgVersion() {
  return EPG_VERSION;
}

/**
 * 获取系统(apk)版本号
 * @returns
 */
function getApkVersion() {
  if (typeof nativeClient != "undefined") {
    return nativeClient.getApkVersion();
  }
  return "1.0.0";
}

/**
 * 获取下一个焦点：水平垂直优先方法（仅在首页内容区）
 * @param {*} dir     方向
 * @param {*} origin  当前点
 * @returns 下一个焦点信息
 */
function getNext(dir, origin) {
  var getIndex1 = function (dir, compare, origin) {
    switch (dir) {
      case "left":
        return compare.calc.right - origin.calc.left;
      case "right":
        return origin.calc.right - compare.calc.left;
      case "up":
        return compare.calc.bottom - origin.calc.top;
      case "down":
        return origin.calc.bottom - compare.calc.top;
    }
  };
  var getIndex2 = function (dir, compare, origin) {
    switch (dir) {
      case "left":
      case "right":
        if (origin.calc.top > compare.calc.bottom) {
          //第一种情况，比较节点完全在源节点上部 优先级2
          return 2;
        } else if (origin.calc.bottom < compare.calc.top) {
          //第一种情况，比较节点完全在源节点下部 优先级1
          return 1;
        } else {
          //第三种情况，比较节点部分或完全在源节点内部 优先级3
          return 3;
        }
      case "up":
      case "down":
        if (origin.calc.left > compare.calc.right) {
          //第一种情况，比较节点完全在源节点左部 优先级2
          return 2;
        } else if (origin.calc.right < compare.calc.left) {
          //第一种情况，比较节点完全在源节点右部 优先级1
          return 1;
        } else {
          //第三种情况，比较节点部分或完全在源节点内部 优先级3
          return 3;
        }
    }
  };
  var getIndex3 = function (dir, compare, origin) {
    switch (dir) {
      case "left":
      case "right":
        if (compare._Index_1 == 2) {
          return compare.calc.bottom;
        } else {
          return -compare.calc.bottom;
        }
      case "up":
      case "down":
        if (compare._Index_1 == 2) {
          return compare.calc.right;
        } else {
          return -compare.calc.right;
        }
    }
  };
  var compares = contentViewCell;
  var findNext = null;
  for (var i = 0; i < compares.length; i++) {
    var compare = compares[i];
    //优先值2 或筛选值
    compare._Index_2 = getIndex1(dir, compare, origin);
    compare._Index_1 = compare._Index_1 = undefined;
    // console.log('_________________________________________');
    // console.log('比较: ' + compare.id)
    if (compare._Index_2 <= 0) {
      if (findNext) {
        compare._Index_1 = getIndex2(dir, compare, origin);
        // console.log(findNext._Index_1)
        if (findNext._Index_1 == undefined) {
          findNext._Index_1 = getIndex2(dir, findNext, origin);
        }
        if (findNext._Index_1 == compare._Index_1) {
          if (findNext._Index_2 == compare._Index_2) {
            compare._Index_3 = getIndex3(dir, compare, origin);
            if (findNext._Index_3 == undefined) {
              findNext._Index_3 = getIndex3(dir, findNext, origin);
            }
            if (findNext._Index_3 <= compare._Index_3) {
              // console.log('优先级3比较: 胜利')
              findNext = compare;
            } else {
              // console.log('优先级3比较: 失败')
            }
          } else if (findNext._Index_2 < compare._Index_2) {
            // console.log('优先级2比较: 胜利')
            findNext = compare;
          } else {
            // console.log('优先级2比较: 失败')
          }
        } else if (findNext._Index_1 < compare._Index_1) {
          // console.log('优先级1比较: 胜利')
          findNext = compare;
        } else {
          // console.log('优先级2比较: 失败')
        }
      } else {
        // console.log('默认值设置')
        findNext = compare;
      }
    } else {
      // console.log('不满足筛选条件')
    }
  }
  return findNext;
}

/**
 * 获取当前时间基础方法，获取date对象的各项属性
 */
function getDateVal() {
  var time = new Date();
  var weekDay = time.getDay(); // 获取星期
  var day = time.getDate();
  var year = time.getFullYear();
  var month = time.getMonth() + 1;
  var hour = time.getHours();
  var minute = time.getMinutes();
  var second = time.getSeconds();
  var mytime = time.toLocaleTimeString(); //获取时间段时间

  var timeObj = {};
  timeObj.year = "" + year;
  timeObj.month = month < 10 ? "0" + month : "" + month;
  timeObj.day = day < 10 ? "0" + day : "" + day;

  timeObj.hour = hour < 10 ? "0" + hour : "" + hour;
  timeObj.minute = minute < 10 ? "0" + minute : "" + minute;
  timeObj.second = second < 10 ? "0" + second : "" + second;

  timeObj.weekDay = weekDay;
  timeObj.mytime = mytime;
  return timeObj;
}

// 获取e相对与compare的定位距离
function getAbsPointClac(e, compare) {
  var _pos_e = e.getBoundingClientRect();
  var _pos_c = compare.getBoundingClientRect();
  return {
    x: _pos_e.left - _pos_c.left,
    y: _pos_e.top - _pos_c.top,
  };
}

/**
 * 设置背景，需要主动调用
 * force 强制重新请求
 */
var address_bg = "";
var address_hotel_logo = "";
function loadPageInfoData(force) {
  var setPageBackGround = function () {
    // todo 处理闪烁 两张图切换的闪烁
    var src = filter.getPicture(address_bg);
    // var img = new Image();
    // img.src = src;
    // img.onload = function () {
    //   $("bg").css("opacity", "0");
    //   $("bg").css("backgroundImage", "url(" + src + ")");
    //   setTimeout(function () {
    //     $("bg").css("opacity", "1");
    //   }, 100);
    // };

    if (!$("bg").node) {
      return;
    }
    $("bg").css("opacity", "0");
    $("bg").css("backgroundImage", "url(" + src + ")");
    $("bg").css("display", "block");
    setTimeout(function () {
      $("bg").css("opacity", "1");
    }, 300);
  };
  var setPageHotelLogo = function () {
    if (!$("hotel_logo").node) {
      return;
    }
    var hotleSrc = filter.getPicture(address_hotel_logo);
    $("hotel_logo").css("opacity", "0");
    $("hotel_logo").css("backgroundImage", "url(" + hotleSrc + ")");
    $("hotel_logo").css("display", "block");
    setTimeout(function () {
      $("hotel_logo").css("opacity", "1");
    }, 300);
  };
  if (!force && address_bg) {
    address_bg = store.get("address_bg");
    setPageBackGround();
  } else if (!force && address_hotel_logo) {
    address_hotel_logo = store.get("hotel_logo");
    setPageHotelLogo();
  } else {
    http.get({
      url: "/api/epg/category/{code}",
      params: {
        code: user.userAuthInfo.baseCategoryCode,
      },
      success: function (res) {
        if (res.code == 200 && res.data && res.data.bgImg) {
          // 防止同图切换
          if (address_bg != res.data.bgImg) {
            address_bg = res.data.bgImg;
            store.set("address_bg", res.data.bgImg);
            setPageBackGround();
          }
        }
        if (res.code == 200 && res.data && res.data.leftIconImg) {
          if (address_hotel_logo != res.data.leftIconImg) {
            address_hotel_logo = res.data.leftIconImg;
            store.set("address_hotel_logo", res.data.leftIconImg);
            setPageHotelLogo();
          }
        }
      },
    });
  }
}

/**
 * 清除自定义缓存
 */
function clearAllDIYStore() {
  // 清除缓存
  store.del("address_bg");
}
(function (window, undefined) {
  var eZone = (function () {
    function Box() {
      this.notShake = true; //默认移除抖动
      this.curIndex = 0;
      this.curPage = 1;
      this.totalEle = 0;
      this.totalPage = 1;
      this.id = undefined;
      this.X = arguments[0] || 0;
      this.Y = arguments[1] || 0;
      this.pageSize = this.X * this.Y;
      this.dirs = arguments[2] || [-1, -1, -1, -1];
      this.eles = arguments[3] || [];
      this.eleBlurAttr = !arguments[4] ? (arguments[4] === null ? arguments[4] : "className:item") : "className:" + arguments[4];
      this.eleFocusAttr = !arguments[5] ? (arguments[5] === null ? arguments[5] : this.eleBlurAttr + " focus") : "className:" + arguments[5];
      this.autoHorizontalFlip = false;
      this.autoVerticalFlip = false;
      this.autoCycleFlip = false;

      this.Arrangement = "X";
      this.lastLineTurn = true;
      this.focusLast = false;
      this.pageTurnKeep = false;
      this.scrollArg = [];
      this.pageTurnFlag = 0;

      this.canSlide = false;
      this.slideEle = undefined;
      this.sliedeMode = "current";
      this.slideParentEle = undefined;
      this.slideType = "auto";
      this.slideOffset = [0, 0, 0, 0];
      this.leftStep = 0;
      this.topStep = 0;

      this.IOIsRecordArr = [false, false, false, false];
      this.IORecordIndexArr = [0, 0, 0, 0];
      this.IORecordAttrArr = [];

      this.darkFlag = false;
      this.darkPage = 1;
      this.darkIndex = -1;
      this.fixedDarkIndex = -1;
      this.darkBlurAttr = this.eleBlurAttr;
      this.autoAddDarkFocus = true;

      this.upEvent = null;
      this.downEvent = null;
      this.leftEvent = null;
      this.rightEvent = null;
      this.dirEventSwitch = true;
      this.boxOkEvent = function () {};
      this.focusEvent = function () {};
      this.blurEvent = function () {};
      this.pageTurnEvent = function () {};
      this.boxOutEvent = function () {};
      this.boxInEvent = function () {};

      this.setDarkfocus = function (changeAfter) {
        this.darkFlag = true;
        this.darkPage = this.curPage;
        this.oldDarkIndex = this.darkIndex;
        if (this.fixedDarkIndex != -1) {
          this.darkIndex = this.fixedDarkIndex;
        } else {
          this.darkIndex = this.curIndex;
        }
        var cureentEle = this.eles[this.darkIndex].htmlEle;
        if (!cureentEle) {
          cureentEle = $$(this.eles[this.darkIndex].htmlEleId);
        }
        var curClassName = cureentEle ? cureentEle.className : "";
        if (curClassName.indexOf("select") != -1 || curClassName.indexOf("focus") != -1) {
          var array = curClassName.split(" ");
          array = array.slice(0, array.length - 1);
          curClassName = array.join(" ");
        }
        this.eles[this.darkIndex].blurAttr = curClassName + " select";
        this.eles[this.darkIndex].focusAttr = curClassName + " focus";
        if (!changeAfter) {
          this.eles[this.darkIndex].changeAttr(this.eles[this.darkIndex].blurAttr);
          if (this.oldDarkIndex != -1) {
            this.eles[this.oldDarkIndex].blurAttr =
              this.eles[this.oldDarkIndex].blurAttr.indexOf(" select") != -1 ? this.eles[this.oldDarkIndex].blurAttr.split(" select")[0] : this.eles[this.oldDarkIndex].blurAttr;
            this.eles[this.oldDarkIndex].changeAttr(this.eles[this.oldDarkIndex].blurAttr);
          }
        }
      };

      this.clearDarkfocus = function (isChangeAttr) {
        if (this.darkIndex != -1) {
          this.eles[this.darkIndex].blurAttr = this.eleBlurAttr;
          this.eles[this.darkIndex].focusAttr = this.eleFocusAttr;
          if (isChangeAttr) {
            this.eles[this.darkIndex].changeAttr(this.eleBlurAttr);
          }
          this.darkIndex = -1;
        }
      };

      this.changeDarkFocus = function () {
        if (this.curPage === this.darkPage) {
          this.eles[this.darkIndex].blurAttr = this.darkBlurAttr;
          this.eles[this.darkIndex].changeAttr(this.darkBlurAttr);
        } else {
          this.eles[this.darkIndex].blurAttr = this.eleBlurAttr;
          this.eles[this.darkIndex].changeAttr(this.eleBlurAttr);
        }
      };

      this.changeDark = function (flag) {
        if (flag) {
          this.eles[this.darkIndex].blurAttr = this.darkBlurAttr;
          this.eles[this.darkIndex].changeAttr(this.darkBlurAttr);
        } else {
          this.eles[this.darkIndex].blurAttr = this.eleBlurAttr;
          this.eles[this.darkIndex].changeAttr(this.eleBlurAttr);
        }
      };

      this.setSlide = function (tempEleId, slideMode, slideParentEleId, slideType, leftStep, topStep, slideOffset) {
        this.canSlide = true;
        this.slideEle = $$(tempEleId);
        this.slideType = slideType;
        this.sliedeMode = slideMode;
        this.slideParentEle = $$(slideParentEleId);
        this.leftStep = leftStep || this.topStep;
        this.topStep = topStep || this.topStep;
        this.slideOffset = slideOffset || this.slideOffset;
      };

      this.changeFocus = function (index, focusOrNot, notCheckIsolated) {
        //孤岛判断：适用于Wrapper.changeFocus(x, y)为孤岛
        if (focusOrNot && !notCheckIsolated && this.eles[index] && this.eles[index].isolated) {
          for (var m = index + 1; m < this.totalEle; m++) {
            if (!this.eles[m].isolated) {
              this.changeFocus(m, true);
              return;
            }
          }
          for (var m = index - 1; m >= 0; m--) {
            if (!this.eles[m].isolated) {
              this.changeFocus(m, true);
              return;
            }
          }
        }
        if (focusOrNot) {
          this.curIndex = index;
          this.focusEvent();
        } else {
          this.blurEvent();
        }
        if (this.canSlide) {
          if (focusOrNot) {
            var curEle = this.eles[index].htmlEle;
            if (!curEle) {
              curEle = $$(this.eles[index].htmlEleId);
            }
            if (curEle !== null && !!this.slideEle) {
              var tempLeft = 0;
              var tempTop = 0;
              if (this.slideType === "auto") {
                tempLeft = this.getAbsPoint(curEle, this.sliedeMode, this.slideParentEle).x;
                tempTop = this.getAbsPoint(curEle, this.sliedeMode, this.slideParentEle).y;
              } else if (this.slideType === "manual") {
                tempLeft = this.slideOffset[0];
                tempTop = this.slideOffset[1];
                if (this.Arrangement === "X") {
                  tempLeft += this.leftStep * (this.curIndex % this.Y);
                  tempTop += this.topStep * Math.floor(this.curIndex / this.Y);
                } else if (this.Arrangement === "Y") {
                  tempLeft += this.leftStep * Math.floor(this.curIndex / this.X);
                  tempTop += this.topStep * (this.curIndex % this.X);
                }
              }
              if (curEle.currentStyle) {
                borderRadius = curEle.currentStyle["borderRadius"];
              } else {
                borderRadius = window.getComputedStyle(curEle, null)["borderRadius"];
              }
              var tempCssText =
                "left:" +
                tempLeft +
                "px;top:" +
                tempTop +
                "px;width:" +
                (curEle.offsetWidth + this.slideOffset[2]) +
                "px;height:" +
                (curEle.offsetHeight + this.slideOffset[3]) +
                "px;border-radius:" +
                borderRadius +
                ";transitionDuration:" +
                this.slideEle.style.transitionDuration +
                ";-webkit-transition-duration:" +
                this.slideEle.style.transitionDuration +
                ";-moz-transition-duration:" +
                this.slideEle.style.transitionDuration +
                ";-o-transition-duration:" +
                this.slideEle.style.transitionDuration;
              this.slideEle.style.cssText = tempCssText;
              if (this.slideEle.style.display === "none") {
                this.slideEle.style.display = "block";
              }
            }
          }
          this.eles[index].toggleFocusEvent(focusOrNot);
          this.eles[index].marqueeScrollEvent(focusOrNot);
        } else {
          this.eles[index].changeFocus(focusOrNot);
        }
      };

      this.move = function (dir, flag) {
        var tempIndex = this.eles[this.curIndex];
        if (tempIndex.moveDirs[dir] != -1) {
          var _nextCurIndex = tempIndex.moveDirs[dir];
          var _next = this.eles[_nextCurIndex];

          if (_next && _next.isolated) {
            //若下一个ele为孤岛
            //孤儿模式/孤岛模式
            //debug 待办：若存在多个孤岛，还需要递归处理直到下一个非孤岛，或传递到边界
            //旨在解决特殊的孤立节点（当前需求为少儿专区-强档推荐的特殊排列）
            var _nextsIndex = _next.moveDirs[dir]; //下一个ele若继续原方向移动后的位置
            if (_nextsIndex != -1) {
              //若为碰壁box
              this.changeFocus(this.curIndex, false); //关闭当前位置focus
              this.curIndex = _nextCurIndex; //先到下一个ele
              this.changeFocus(this.curIndex, true, true); //打开当前位置focus
              //行进到下一个位置
              Wrapper.move(dir); //再离开box边界
            } else {
              //若为非碰壁box
              var _is_move = false; //是否移动的标志 此检测存在bug，应当配合方向检测
              console.log(_nextCurIndex - this.Y);
              if (_nextCurIndex - this.Y >= 0) {
                _nextsIndex = _nextCurIndex - this.Y;
                _is_move = true;
              } else if (_nextCurIndex + this.Y < this.totalEle) {
                _nextsIndex = _nextCurIndex + this.Y;
                _is_move = true;
              }
              if (_is_move) {
                //若能移动
                console.log(this.curIndex, _nextCurIndex);
                this.changeFocus(this.curIndex, false);
                this.curIndex = _nextsIndex;
                this.changeFocus(this.curIndex, true);
              } else {
                var box_now = Wrapper.boxes[Wrapper.curBoxId];
                if (!box_now.notShake) {
                  var ele_now = box_now.eles[box_now.curIndex];
                  var dom_now = $$(ele_now.htmlEleId);
                  if (dom_now) {
                    setShakeAnimation(dom_now, dir);
                  }
                }
              }
            }
            return;
          } else {
            if (!flag) {
              this.changeFocus(this.curIndex, false);
            }
            this.curIndex = _nextCurIndex;
          }

          if (tempIndex.moveDirs[dir] >= this.totalEle) {
            this.curIndex = this.totalEle - 1;
          }
          this.changeFocus(this.curIndex, true);
        }
      };

      this.setBoxMoveArray = function (toBox, dir) {
        var str = "";
        if (dir == 0) {
          var len = this.totalEle > this.Y ? this.Y : this.totalEle;
          var start = (Math.ceil(toBox.totalEle / toBox.Y) - 1) * toBox.Y;
          for (var i = 0; i < len; i++) {
            var toId = start + i;
            if (toId >= toBox.totalEle) {
              toId = toBox.totalEle;
            }
            str += i + "-" + toBox.id + ">" + toId;
            if (i != len - 1) {
              str += ",";
            }
          }
        } else if (dir == 2) {
          var start = (Math.ceil(this.totalEle / this.Y) - 1) * this.Y;
          var len = this.totalEle - start;
          for (var i = 0; i < len; i++) {
            var toId = i >= toBox.totalEle ? toBox.totalEle - 1 : i;
            str += start + i + "-" + toBox.id + ">" + toId;
            if (i != len - 1) {
              str += ",";
            }
          }
        }
        var array = [-1, -1, -1, -1];
        array[dir] = str;
        this.setMoveArray(array[0], array[1], array[2], array[3]);
      };

      this.ok = function () {
        this.boxOkEvent();
        this.eles[this.curIndex].ok();
      };

      this.boxIn = function (index, dir) {
        this.boxInEvent(index, dir);
        Wrapper.curBoxId = this.id;
        var tempIndex = index;
        if (!!this.totalEle && tempIndex > this.totalEle - 1) {
          tempIndex = this.totalEle - 1;
        }
        var tempDir = (dir + 2) % 4;
        if (this.IOIsRecordArr[tempDir]) {
          tempIndex = this.IORecordIndexArr[tempDir];
        }

        var canChangeFlag = false;
        if (this.eles[index] && this.eles[index].isolated) {
          var check_dir_up = function (index, box) {
            for (var n = index - box.Y; n >= 0; n -= box.Y) {
              if (!box.eles[n].isolated) {
                return n;
              }
            }
            return -1;
          };
          var check_dir_left = function (index, box) {
            var _left_index = index - (index % box.Y);
            for (var n = index - 1; n >= _left_index; n--) {
              if (!box.eles[n].isolated) {
                return n;
              }
            }
            return -1;
          };
          var check_dir_down = function (index, box) {
            for (var n = index + box.Y; n < box.totalEle; n += box.Y) {
              if (!box.eles[n].isolated) {
                return n;
              }
            }
            return -1;
          };
          var check_dir_right = function (index, box) {
            var _right_index = index + (box.Y - (index % box.Y) - 1);
            for (var n = index + 1; n <= _right_index; n++) {
              if (!box.eles[n].isolated) {
                return n;
              }
            }
            return -1;
          };
          //向下 或 向上
          var _tempIndex_temp = -1;
          if (dir === 0 || dir === 2) {
            if (dir === 0) {
              //向上
              if ((_tempIndex_temp = check_dir_up(index, this)) != -1) {
                tempIndex = _tempIndex_temp;
              }
            } else {
              //向下
              if ((_tempIndex_temp = check_dir_down(index, this)) != -1) {
                tempIndex = _tempIndex_temp;
              }
            }
            if (_tempIndex_temp == -1) {
              //向左
              if ((_tempIndex_temp = check_dir_left(index, this)) != -1) {
                tempIndex = _tempIndex_temp;
              }
            }
            if (!canChangeFlag) {
              //向右
              if ((_tempIndex_temp = check_dir_right(index, this)) != -1) {
                tempIndex = _tempIndex_temp;
              }
            }
          } else {
            if (dir === 1) {
              //向左
              if ((_tempIndex_temp = check_dir_left(index, this)) != -1) {
                tempIndex = _tempIndex_temp;
              }
            } else {
              //向右
              if ((_tempIndex_temp = check_dir_right(index, this)) != -1) {
                tempIndex = _tempIndex_temp;
              }
            }
            if (_tempIndex_temp == -1) {
              //向上
              if ((_tempIndex_temp = check_dir_up(index, this)) != -1) {
                tempIndex = _tempIndex_temp;
              }
            }
            if (!canChangeFlag) {
              //向下
              if ((_tempIndex_temp = check_dir_down(index, this)) != -1) {
                tempIndex = _tempIndex_temp;
              }
            }
          }
        }

        this.changeFocus(tempIndex, true);

        if (this.fixedDarkIndex == -1) {
          if (this.autoAddDarkFocus) {
            this.clearDarkfocus();
          }
        }
      };

      this.boxOut = function (index, dir) {
        this.boxOutEvent(index, dir);
        if (this.autoAddDarkFocus) {
          this.setDarkfocus();
        }
        var tempIndex = index;
        if (!!this.totalEle && tempIndex > this.totalEle - 1) {
          tempIndex = this.totalEle - 1;
        }
        if (this.IOIsRecordArr[dir]) {
          this.IORecordIndexArr[dir] = tempIndex;
          if (this.darkFlag && this.curPage === this.darkPage) {
            this.IORecordIndexArr[dir] = this.darkIndex;
          }

          if (this.IORecordAttrArr[dir] !== undefined && !this.darkFlag) {
            this.eles[tempIndex].changeAttr(this.IORecordAttrArr[dir]);
            this.eles[tempIndex].toggleFocusEvent(false);
            this.eles[tempIndex].marqueeScrollEvent(false);
          } else {
            this.changeFocus(tempIndex, false);
          }
        } else {
          this.changeFocus(tempIndex, false);
        }
      };

      this.pageTurn = function (num) {
        if (this.totalPage > 1) {
          var nextPage = this.curPage + num;
          if (nextPage > this.totalPage) {
            if (this.autoCycleFlip) {
              nextPage = 1;
            } else {
              return;
            }
          } else if (nextPage < 1) {
            if (this.autoCycleFlip) {
              nextPage = this.totalPage;
            } else {
              return;
            }
          }
          this.curPage = nextPage;
          this.pageTurnFlag = num;
          this.boxPageTurnEvent(num);
        }
      };

      this.boxPageTurnEvent = function () {
        this.pageTurnEvent();
      };

      this.pageTurnEnd = function () {
        if (this.pageTurnFlag !== 0) {
          this.setScrollEvent();
          if (this.darkFlag) {
            // this.changeDarkFocus();
          }
          this.changeFocus(this.curIndex, false);
          var nextIndexId = 0;
          if (this.pageTurnFlag === 1) {
            nextIndexId = 0;
          } else if (this.pageTurnFlag === -1) {
            nextIndexId = this.totalEle - 1;
          }
          if (this.pageTurnKeep) {
            if (this.autoVerticalFlip) {
              if (this.Arrangement === "X") {
                var curIndexPositionV = this.curIndex % this.Y;
                var endIndexPositionV = (this.totalEle - 1) % this.Y;
                var preEndLinesV = Math.ceil(this.totalEle / this.Y);
                if (this.pageTurnFlag === 1) {
                  if (curIndexPositionV < this.totalEle) {
                    this.changeFocus(curIndexPositionV, true);
                  } else {
                    this.changeFocus(this.totalEle - 1, true);
                  }
                } else {
                  if (curIndexPositionV <= endIndexPositionV) {
                    this.changeFocus((preEndLinesV - 1) * this.Y + curIndexPositionV, true);
                  } else {
                    this.changeFocus(this.totalEle - 1, true);
                  }
                }
              } else if (this.Arrangement === "Y") {
                var curColumnV = Math.ceil((this.curIndex + 1) / this.X);
                var goColumnV = Math.ceil(this.totalEle / this.X);
                if (this.pageTurnFlag === 1) {
                  if (goColumnV < curColumnV) {
                    this.changeFocus((goColumnV - 1) * this.X, true);
                  } else {
                    this.changeFocus((curColumnV - 1) * this.X, true);
                  }
                } else {
                  if (goColumnV <= curColumnV) {
                    this.changeFocus(this.totalEle - 1, true);
                  } else {
                    this.changeFocus(curColumnV * this.X - 1, true);
                  }
                }
              }
            } else if (this.autoHorizontalFlip) {
              if (this.Arrangement === "X") {
                var curColumnH = Math.ceil((this.curIndex + 1) / this.Y);
                var goColumnH = Math.ceil(this.totalEle / this.Y);
                if (this.pageTurnFlag === 1) {
                  if (goColumnH < curColumnH) {
                    this.changeFocus((goColumnH - 1) * this.Y, true);
                  } else {
                    this.changeFocus((curColumnH - 1) * this.Y, true);
                  }
                } else {
                  if (goColumnH <= curColumnH) {
                    this.changeFocus(this.totalEle - 1, true);
                  } else {
                    this.changeFocus(curColumnH * this.Y - 1, true);
                  }
                }
              } else if (this.Arrangement === "Y") {
                var curIndexPositionH = this.curIndex % this.X;
                var endIndexPositionH = (this.totalEle - 1) % this.X;
                var preEndLinesH = Math.ceil(this.totalEle / this.X);
                if (this.pageTurnFlag === 1) {
                  if (curIndexPositionH < this.totalEle) {
                    this.changeFocus(curIndexPositionH, true);
                  } else {
                    this.changeFocus(this.totalEle - 1, true);
                  }
                } else {
                  if (curIndexPositionH <= endIndexPositionH) {
                    this.changeFocus((preEndLinesH - 1) * this.X + curIndexPositionH, true);
                  } else {
                    this.changeFocus(this.totalEle - 1, true);
                  }
                }
              }
            } else {
              this.changeFocus(nextIndexId, true);
            }
          } else {
            this.changeFocus(nextIndexId, true);
          }
        }
      };

      this.setMoveArray = function (a, b, c, d) {
        var array = [a, b, c, d];
        for (var j = 0; j < 4; j++) {
          var moveStrArr = array[j];
          if (typeof moveStrArr === "string" && moveStrArr !== "-1") {
            var moveIndexs = moveStrArr.split(",");
            var ml = moveIndexs.length;
            for (var i = 0; i < ml; i++) {
              var tempMoveIndex = moveIndexs[i].split("-");
              if (this.eles[tempMoveIndex[0]]) {
                this.eles[tempMoveIndex[0]].moveDirs[j] = tempMoveIndex[1];
              }
            }
          }
        }
      };

      this.setBoxDir = function (dir, boxId, boxIndex) {
        var preDir = this.dirs[dir];
        var l = this.eles.length;
        this.dirs[dir] = boxId;
        for (var i = 0; i < l; i++) {
          var tempDir = this.eles[i].moveDirs[dir].toString();
          if ((tempDir.indexOf(">") != -1 && tempDir.indexOf(preDir) === 0) || tempDir == -1) {
            if (boxId == -1) {
              this.eles[i].moveDirs[dir] = boxId;
            } else {
              if (boxIndex) {
                this.eles[i].moveDirs[dir] = boxId + ">" + boxIndex;
              } else {
                this.eles[i].moveDirs[dir] = boxId + ">0";
              }
            }
          }
        }
      };

      this.setBoxCircleEle = function (type) {
        if (type === "X") {
          this.eles[0].moveDirs[1] = this.eles.length - 1;
          this.eles[this.eles.length - 1].moveDirs[3] = 0;
        } else if (type === "Y") {
          this.eles[0].moveDirs[0] = this.eles.length - 1;
          this.eles[this.eles.length - 1].moveDirs[2] = 0;
        }
      };

      this.setViewArrangement = function (type) {
        var X = this.X;
        var Y = this.Y;
        var dirs = this.dirs;
        var l = this.eles.length;
        this.Arrangement = type;
        if (type === "X") {
          for (var i = 0; i < l; i++) {
            var tempDirs = [
              i - Y < 0 ? (dirs[0] === -1 ? -1 : dirs[0] + ">0") : i - Y,
              i % Y === 0 ? (dirs[1] === -1 ? -1 : dirs[1] + ">0") : i - 1,
              i + Y > X * Y - 1 ? (dirs[2] === -1 ? -1 : dirs[2] + ">0") : i + Y,
              i % Y === Y - 1 ? (dirs[3] === -1 ? -1 : dirs[3] + ">0") : i + 1,
            ];
            this.eles[i].moveDirs = tempDirs;
          }
        } else if (type === "Y") {
          for (var k = 0; k < l; k++) {
            var tempDirsK = [
              k % X === 0 ? (dirs[0] === -1 ? -1 : dirs[0] + ">0") : k - 1,
              k - X < 0 ? (dirs[1] === -1 ? -1 : dirs[1] + ">0") : k - X,
              k % X === X - 1 ? (dirs[2] === -1 ? -1 : dirs[2] + ">0") : k + 1,
              k + X > X * Y - 1 ? (dirs[3] === -1 ? -1 : dirs[3] + ">0") : k + X,
            ];
            this.eles[k].moveDirs = tempDirsK;
          }
        }
      };

      this.clearEles = function () {
        var l = this.eles.length;
        for (var i = 0; i < l; i++) {
          this.eles[i].htmlEle = null;
          this.eles[i].scrollEle = null;
        }
      };

      this.setScrollEvent = function () {
        var _arguments = arguments;
        if (_arguments.length > 0) {
          this.scrollArg = _arguments;
        } else if (this.scrollArg.length > 0) {
          _arguments = this.scrollArg;
        }
        var elePrefix = _arguments[0] || "";
        var l = _arguments[1] || 0;
        var isEllipsis = _arguments[_arguments.length - 1];
        if (_arguments.length > 2) {
          if (typeof _arguments[2] === "boolean") {
            var el = this.eles.length;
            for (var i = 0; i < el; i++) {
              if (!!$$(elePrefix + i)) {
                this.eles[i].scrollId = elePrefix + i;
                this.eles[i].scrollText = $$(elePrefix + i).innerHTML;
                this.eles[i].scrollCutStr = Util.getCutedStr(this.eles[i].scrollText, parseInt(l), isEllipsis);
                // this.eles[i].marqueeScrollEvent(false);
              }
            }
          } else if (Util.isArray(_arguments[2])) {
            var al = _arguments[2].length;
            for (var k = 0; k < al; k++) {
              var index = _arguments[2][k];
              if (!!$$(elePrefix + index) && typeof index === "number") {
                this.eles[index].scrollId = elePrefix + index;
                this.eles[index].scrollText = $$(elePrefix + index).innerHTML;
                this.eles[index].scrollCutStr = Util.getCutedStr(this.eles[index].scrollText, parseInt(l), isEllipsis);
                // this.eles[index].marqueeScrollEvent(false);
              }
            }
          }
        }
      };

      this.getAbsPoint = function (e, type, parentEle) {
        var x = e.offsetLeft,
          y = e.offsetTop,
          _e = e.offsetParent;
        if (type != "current") {
          while ((_e != parentEle && type == "parent") || (_e && type == "document")) {
            x += _e.offsetLeft;
            y += _e.offsetTop;
            _e = _e.offsetParent;
          }
        }
        return { x: x, y: y };
      };
    }

    function Ele() {
      this.htmlEle = undefined;
      this.eleUrl = undefined;
      this.htmlEleId = arguments[0] || "";
      this.blurAttr = !arguments[1] ? (arguments[1] === null ? arguments[1] : "className:item") : "className:" + arguments[1];
      this.focusAttr = !arguments[2] ? (arguments[2] === null ? arguments[2] : this.blurAttr + " focus") : "className:" + arguments[2];
      this.moveDirs = arguments[3] || [-1, -1, -1, -1];
      this.useMarquee = false;
      this.scrollEle = undefined;
      this.scrollId = "";
      this.scrollCutStr = "";
      this.scrollText = "";
      this.scrollTimer = null;
      this.scrollEvent = function () {};

      this.eleOkEvent = function () {};
      this.focusEvent = function () {};
      this.blurEvent = function () {};

      this.ok = function () {
        this.eleOkEvent();
        if (!!this.eleUrl) {
          window.location = this.eleUrl;
        }
      };

      this.changeFocus = function (focusOrNot) {
        this.changeFocusAttr(focusOrNot);
        // if (focusOrNot) {
        //
        //   this.changeAttr(this.focusAttr);
        // } else {
        //   this.changeAttr(this.blurAttr);
        // }
        this.toggleFocusEvent(focusOrNot);
        this.marqueeScrollEvent(focusOrNot);
      };

      this.changeFocusAttr = function (focusOrNot) {
        if (!this.htmlEle) {
          this.htmlEle = $$(this.htmlEleId);
        }
        if (!this.htmlEle) {
          return;
        }
        if (focusOrNot) {
          var curClassName = this.htmlEle.className;
          if (curClassName.indexOf("select") != -1) {
            var array = curClassName.split(" ");
            array = array.slice(0, array.length - 1);
            curClassName = array.join(" ");
          }
          this.htmlEle.className = curClassName + " focus";
        } else {
          var curClassName = this.htmlEle.className;
          var select = "";
          if (this.blurAttr.indexOf("select") != -1 && curClassName.indexOf("select") == -1) {
            select = " select";
          }
          this.htmlEle.className = this.htmlEle.className.split(" focus")[0] + select;
        }
      };

      this.marqueeScrollEvent = function (focusOrNot) {
        if (focusOrNot) {
          if (this.scrollCutStr !== this.scrollText) {
            if (this.useMarquee) {
              if (!this.scrollEle) {
                this.scrollEle = $$(this.scrollId);
              }
              if (this.scrollEle !== null) {
                this.scrollEle.innerHTML = "<marquee direction='left' scrolldelay='150'>" + this.scrollText + "</marquee>";
              }
            } else {
              if (!this.scrollEle) {
                this.scrollEle = $$(this.scrollId);
              }
              if (this.scrollEle !== null) {
                var nodeWidth = this.scrollEle.scrollWidth;
                var parentWidth = this.scrollEle.parentNode.offsetWidth;
                var scrollLeft = this.scrollEle.offsetLeft;
                this.scrollLeft = this.scrollEle.offsetLeft;
                var scrollEle = this.scrollEle;
                this.scrollTimer = window.setInterval(function () {
                  if (scrollLeft > 0 - nodeWidth) {
                    scrollLeft -= 1;
                  } else {
                    scrollLeft = parentWidth;
                  }
                  scrollEle.style.left = scrollLeft + "px";
                }, 30);
              }
            }
          }
        } else {
          if (this.scrollCutStr !== this.scrollText) {
            if (!this.scrollEle) {
              this.scrollEle = $$(this.scrollId);
            }
            if (this.useMarquee) {
              if (this.scrollEle !== null) {
                this.scrollEle.innerHTML = this.scrollCutStr;
              }
            } else {
              if (this.scrollEle !== null) {
                this.scrollEle.style.left = this.scrollLeft + "px";
              }
              window.clearTimeout(this.scrollTimer);
              this.scrollTimer = null;
            }
          }
        }
      };

      this.toggleFocusEvent = function (focusOrNot) {
        if (focusOrNot) {
          this.focusEvent();
        } else {
          this.blurEvent();
        }
      };

      this.changeAttr = function (tempAttr) {
        if (!!tempAttr) {
          if (tempAttr.indexOf(":") == -1) {
            tempAttr = "className:" + tempAttr;
          }
          var tempProperty = tempAttr.toString().split(":");
          if (!this.htmlEle) {
            this.htmlEle = $$(this.htmlEleId);
          }
          if (this.htmlEle !== null) {
            this.htmlEle[tempProperty[0]] = tempProperty[1];
          }
        }
      };
    }

    function $$(id) {
      return document.getElementById(id);
    }

    function createBox(X, Y, dirs, id, elesUnfocusAttr, elesFocusAttr) {
      var eles = [];
      var l = X * Y;
      for (var i = 0; i < l; i++) {
        var tempDirs = [
          i - Y < 0 ? (dirs[0] === -1 ? -1 : dirs[0] + ">0") : i - Y,
          i % Y === 0 ? (dirs[1] === -1 ? -1 : dirs[1] + ">0") : i - 1,
          i + Y > X * Y - 1 ? (dirs[2] === -1 ? -1 : dirs[2] + ">0") : i + Y,
          i % Y === Y - 1 ? (dirs[3] === -1 ? -1 : dirs[3] + ">0") : i + 1,
        ];
        var domId = typeof id == "string" ? id + i : "box" + id + "_" + i;
        eles[i] = new Ele(domId, elesUnfocusAttr, elesFocusAttr, tempDirs);
      }

      return new Box(X, Y, dirs, eles, elesUnfocusAttr, elesFocusAttr);
    }

    function BoxInstance(X, Y, dirs, id, elesUnfocusAttr, elesFocusAttr) {
      var tempBox = createBox(X, Y, dirs, id, elesUnfocusAttr, elesFocusAttr);
      if (typeof id == "number") {
        tempBox.id = id;
        Wrapper.boxes[id] = tempBox;
        tempBox.totalEle = X * Y;
      } else {
        tempBox.id = id;
        Wrapper.boxes.push(tempBox);
        tempBox.id = typeof id == "number" ? id : Wrapper.boxes.length - 1;
        tempBox.totalEle = X * Y;
      }
      return tempBox;
    }

    function updateBox(box, X, Y, dirs, elesIdStr, elesUnfocusAttr, elesFocusAttr) {
      var tempBox = createBox(X, Y, dirs, elesIdStr, elesUnfocusAttr, elesFocusAttr);
      tempBox.id = box.id;
      tempBox.totalEle = X * Y;
      Wrapper.boxes[tempBox.id] = tempBox;
      return tempBox;
    }

    return {
      $$: $$,
      Box: Box,
      Ele: Ele,
      BoxInstance: BoxInstance,
      updateBox: updateBox,
    };
  })();
  window.$$ = eZone.$$;
  window.eZone = eZone;
})(window);
(function (window, undefined) {
  var Wrapper = {
    curBoxId: 0,
    indexId: 0,
    boxes: [],
    keyPressLock: false,
    dir: undefined,
    backUrl: undefined,
    pressKey_direction: [],
    pressKEy_reStart_time: 15000,

    t_num: undefined,
    channelNumCount: 0,
    tempChannelNum: 0,
    channelNum: 0,
    backFlag: true,
    goToChannelURLEvent: function () {},
    pressKey_dir_event: function (dir) {
      var time = Date.now();
      var key = Util.getStore("pressKey_direction");
      Wrapper.pressKey_direction = key ? JSON.parse(key) : [];
      if (this.pressKey_direction.length > 0) {
        var lastTime = this.pressKey_direction.slice(-1)[0].time;
        if (time - lastTime > this.pressKEy_reStart_time) {
          this.pressKey_direction = [];
        }
      }
      this.pressKey_direction.push({
        direction: dir,
        time: time,
      });
      var str = JSON.stringify(Wrapper.pressKey_direction);
      Util.setStore("pressKey_direction", str);
      if (typeof MOVE_PAGE_NAME != "undefined" && Util.getPageName().indexOf(MOVE_PAGE_NAME)) {
        var num = Wrapper.pressKey_direction.length;
        Wrapper.moveEvent(num);
      }
    },
    volumeUpEvent: function () {},
    volumeDownEvent: function () {},
    volumeMuteEvent: function () {},
    utilityEvent: function () {},
    goHomePageEvent: function () {},
    okEvent: function () {},
    moveEvent: function () {},
    backEvent: function () {},
    delEvent: function () {},
    numTypeEvent: function () {},
    defaultKeyEvent: function () {},

    init: function () {
      var pageName = Util.getPageName();
      var focusStr = Util.getStore(pageName, true);
      var focusObj;
      if (focusStr && focusStr != "undefined") {
        focusObj = typeof focusStr == "object" ? focusStr : JSON.parse(focusStr);
      }
      Util.delStore(pageName);
      var urlArray = [];
      if (Util.getStore("lastUrl")) {
        urlArray = Util.getStore("lastUrl").split("|");
      }
      var backUrl = urlArray[urlArray.length - 1];
      if (focusObj) {
        this.isBack = true;
        if (focusObj.curBoxId != undefined) {
          this.curBoxId = focusObj.curBoxId;
        } else {
          this.curBoxId = arguments[1] || 0;
        }
        if (focusObj.curIndex != undefined) {
          this.indexId = focusObj.curIndex;
        } else {
          this.indexId = arguments[2] || 0;
        }
        if (focusObj.focusObj) {
          this.focusObj = focusObj.focusObj;
        }
      } else {
        this.curBoxId = arguments[1] || 0;
        this.indexId = arguments[2] || 0;
      }
      var bl = this.boxes.length;
      for (var i = 0; i < bl; i++) {
        if (this.boxes[i]) {
          this.boxes[i].id = i;
        } else {
          this.boxes[i] = {
            curPage: 1,
            darkPage: 1,
            darkIndex: 0,
          };
        }
        if (focusObj) {
          var element = focusObj.datas[i];
          this.boxes[i].curPage = element.curPage;
          this.boxes[i].darkPage = element.darkPage;
          this.boxes[i].darkIndex = element.darkIndex;
        }
      }
      this.backUrl = backUrl;
      arguments[3] && arguments[3]();
      if (this.boxes[this.curBoxId]) {
        this.boxes[this.curBoxId].changeFocus(this.indexId, true);
      }
    },

    reInit: function () {
      this.boxes = arguments[0] || [];
      var bl = this.boxes.length;
      for (var i = 0; i < bl; i++) {
        this.boxes[i].id = i;
      }
    },

    numType: function (num) {
      this.numTypeEvent(num);
    },

    goChannelEvent: function (num) {
      this.createNumPanel(num);
      this.showChannelNum(num);
      if (this.t_num !== undefined) {
        clearTimeout(this.t_num);
      }
      this.t_num = setTimeout(this.goToChannelURLEvent, 3000);
    },

    createNumPanel: function (num) {
      if (eZone.$$("channelNumPanel") === null) {
        var channelNumDiv = document.createElement("div");
        channelNumDiv.id = "channelNumPanel";
        channelNumDiv.style.color = "#66cc00";
        channelNumDiv.style.fontSize = "50px";
        channelNumDiv.style.left = "1120px";
        channelNumDiv.style.top = "30px";
        channelNumDiv.style.fontWeight = "bold";
        channelNumDiv.style.position = "absolute";
        channelNumDiv.style.zIndex = 20;
        if (document.body !== null) {
          document.body.appendChild(channelNumDiv);
        }
      }
      eZone.$$("channelNumPanel").style.display = "block";
    },

    showChannelNum: function (num) {
      this.channelNumCount++;
      if (this.channelNumCount > 3) {
        return true;
      }
      this.tempChannelNum = this.tempChannelNum * 10 + num;
      this.channelNum = this.tempChannelNum;
      if (eZone.$$("channelNumPanel") !== null) {
        eZone.$$("channelNumPanel").innerHTML = this.channelNum;
      }
    },

    saveFocus: function (focusObj, clearHis) {
      if (!clearHis) {
        var curBox = this.boxes[this.curBoxId];
        var l = this.boxes.length;
        var curFocStr = '{"curBoxId":' + curBox.id + ',"curIndex":' + curBox.curIndex + ',"datas":[';
        for (var i = 0; i < l; i++) {
          curBox = this.boxes[i];
          curFocStr += '{"darkIndex":' + (curBox ? curBox.darkIndex : 0) + ',"curPage":' + (curBox ? curBox.curPage : 1) + ',"darkPage":' + (curBox ? curBox.darkPage : 1);
          curFocStr += "},";
        }
        curFocStr = curFocStr.substr(0, curFocStr.length - 1);
        curFocStr += "]";
        if (focusObj) {
          curFocStr += ',"focusObj":' + JSON.stringify(focusObj) + "}";
        } else {
          curFocStr += "}";
        }
      }
      var pageName = Util.getPageName();
      var pageUrl = window.location.href;
      var curPageUrl = Util.getStore("lastUrl");
      pageUrl = curPageUrl + "|" + pageUrl;
      Util.setStore("lastUrl", pageUrl);
      Util.setStore(pageName, curFocStr);
    },

    move: function (dir) {
      this.dir = dir;
      var num = dir === 0 || dir === 1 ? -1 : 1;
      var tempBox = this.boxes[this.curBoxId];
      if (!tempBox) {
        return;
      }
      var tempIndex = tempBox.eles[tempBox.curIndex];
      var tempDir = tempIndex.moveDirs[dir];

      if (dir === 0) {
        if (tempBox.upEvent && tempBox.dirEventSwitch) {
          if (!tempBox.upEvent()) return;
        }
        if (tempBox.goUpEvent) {
          tempBox.goUpEvent();
        }
        if (tempBox.autoVerticalFlip) {
          if (tempBox.curPage > 1 || tempBox.autoCycleFlip) {
            if (tempBox.Arrangement === "X") {
              if (tempBox.curIndex < tempBox.Y) {
                tempBox.pageTurn(num);
                if (!tempBox.dirEventSwitch) {
                  tempBox.dirEventSwitch = true;
                }
                return;
              }
            } else if (tempBox.Arrangement === "Y") {
              if (tempBox.curIndex % tempBox.X === 0) {
                tempBox.pageTurn(num);
                if (!tempBox.dirEventSwitch) {
                  tempBox.dirEventSwitch = true;
                }
                return;
              }
            }
          }
        }
      } else if (dir === 1) {
        if (tempBox.leftEvent && tempBox.dirEventSwitch) {
          if (!tempBox.leftEvent()) return;
        }
        if (tempBox.goLeftEvent) {
          tempBox.goLeftEvent();
        }
        if (tempBox.autoHorizontalFlip) {
          if (tempBox.curPage > 1 || tempBox.autoCycleFlip) {
            if (tempBox.Arrangement === "X") {
              if (tempBox.curIndex % tempBox.Y === 0) {
                tempBox.pageTurn(num);
                if (!tempBox.dirEventSwitch) {
                  tempBox.dirEventSwitch = true;
                }
                return;
              }
            } else if (tempBox.Arrangement === "Y") {
              if (tempBox.curIndex < tempBox.X) {
                tempBox.pageTurn(num);
                if (!tempBox.dirEventSwitch) {
                  tempBox.dirEventSwitch = true;
                }
                return;
              }
            }
          }
        }
      } else if (dir === 2) {
        if (tempBox.downEvent && tempBox.dirEventSwitch) {
          if (!tempBox.downEvent()) return;
        }
        if (tempBox.goDownEvent) {
          tempBox.goDownEvent();
        }
        if (tempBox.autoVerticalFlip) {
          if (
            tempBox.focusLast &&
            tempBox.curPage === tempBox.totalPage &&
            (Math.ceil(tempBox.totalEle / tempBox.Y) - 1) * tempBox.Y > tempBox.curIndex &&
            tempBox.curIndex > tempBox.totalEle - 1 - tempBox.Y
          ) {
            tempBox.changeFocus(tempBox.curIndex, false);
            tempBox.changeFocus(tempBox.totalEle - 1, true);
            return;
          }
          if (tempBox.curPage < tempBox.totalPage || tempBox.autoCycleFlip) {
            if (tempBox.Arrangement === "X") {
              if (tempBox.lastLineTurn) {
                if (Math.ceil((tempBox.curIndex + 1) / tempBox.Y) === Math.ceil(tempBox.totalEle / tempBox.Y)) {
                  tempBox.pageTurn(num);
                  if (!tempBox.dirEventSwitch) {
                    tempBox.dirEventSwitch = true;
                  }
                  return;
                }
              } else if (tempBox.curIndex + tempBox.Y > tempBox.totalEle - 1) {
                tempBox.pageTurn(num);
                if (!tempBox.dirEventSwitch) {
                  tempBox.dirEventSwitch = true;
                }
                return;
              }
            } else if (tempBox.Arrangement === "Y") {
              if (tempBox.curIndex % tempBox.X === tempBox.X - 1 || tempBox.curIndex === tempBox.totalEle - 1) {
                tempBox.pageTurn(num);
                if (!tempBox.dirEventSwitch) {
                  tempBox.dirEventSwitch = true;
                }
                return;
              }
            }
          }
        }
      } else if (dir === 3) {
        if (tempBox.rightEvent && tempBox.dirEventSwitch) {
          if (!tempBox.rightEvent()) return;
        }
        if (tempBox.goRightEvent) {
          tempBox.goRightEvent();
        }
        if (tempBox.autoHorizontalFlip) {
          if (tempBox.focusLast && (Math.ceil(tempBox.totalEle / tempBox.X) - 1) * tempBox.X > tempBox.curIndex && tempBox.curIndex > tempBox.totalEle - 1 - tempBox.X) {
            tempBox.changeFocus(tempBox.curIndex, false);
            tempBox.changeFocus(tempBox.totalEle - 1, true);
            return;
          }
          if (tempBox.curPage < tempBox.totalPage || tempBox.autoCycleFlip) {
            if (tempBox.Arrangement === "X") {
              if (tempBox.curIndex % tempBox.Y === tempBox.Y - 1 || tempBox.curIndex === tempBox.totalEle - 1) {
                tempBox.pageTurn(num);
                if (!tempBox.dirEventSwitch) {
                  tempBox.dirEventSwitch = true;
                }
                return;
              }
            } else if (tempBox.Arrangement === "Y") {
              if (tempBox.lastLineTurn) {
                if (Math.ceil((tempBox.curIndex + 1) / tempBox.X) === Math.ceil(tempBox.totalEle / tempBox.X)) {
                  tempBox.pageTurn(num);
                  if (!tempBox.dirEventSwitch) {
                    tempBox.dirEventSwitch = true;
                  }
                  return;
                }
              } else if (tempBox.curIndex + tempBox.X > tempBox.totalEle - 1) {
                tempBox.pageTurn(num);
                if (!tempBox.dirEventSwitch) {
                  tempBox.dirEventSwitch = true;
                }
                return;
              }
            }
          }
        }
      }
      if (!tempBox.dirEventSwitch) {
        tempBox.dirEventSwitch = true;
      }
      if (tempDir != -1) {
        if (typeof tempDir === "string" && tempDir.indexOf(">") > -1) {
          var endBoxId = parseInt(tempDir.split(">")[0]);
          var endIndex = parseInt(tempDir.split(">")[1]);
          if (endBoxId > this.boxes.length - 1 || this.boxes[endBoxId].totalEle <= 0) {
            _setAnima();
            return;
          }
          tempBox.boxOut(tempBox.curIndex, dir);
          if (this.boxes.length > endBoxId) {
            if ((!this.boxes[endBoxId].canSlide && tempBox.canSlide) || (this.boxes[endBoxId].canSlide && tempBox.canSlide && this.boxes[endBoxId].slideEle != tempBox.slideEle)) {
              tempBox.slideEle.style.display = "none";
            }
            this.boxes[endBoxId].boxIn(endIndex, dir);
          }
        } else if (
          (dir == 2 && typeof tempDir === "number" && tempBox.curIndex >= (Math.ceil(tempBox.totalEle / tempBox.Y) - 1) * tempBox.Y) ||
          (dir === 3 && typeof tempDir === "number" && tempBox.curIndex >= tempBox.totalEle - 1)
        ) {
          var endBoxIdn = tempBox.dirs[dir];
          if (endBoxIdn === -1 || this.boxes[endBoxIdn].totalEle <= 0) {
            _setAnima();
            return;
          }
          tempBox.boxOut(tempBox.curIndex, dir);
          if (this.boxes.length > endBoxIdn) {
            if ((!this.boxes[endBoxIdn].canSlide && tempBox.canSlide) || (this.boxes[endBoxIdn].canSlide && tempBox.canSlide && this.boxes[endBoxIdn].slideEle != tempBox.slideEle)) {
              tempBox.slideEle.style.display = "none";
            }
            this.boxes[endBoxIdn].boxIn(0, dir);
          }
        } else {
          tempBox.move(dir);
        }
      } else {
        _setAnima();
      }

      function _setAnima() {
        var box_now = Wrapper.boxes[Wrapper.curBoxId];
        if (!box_now.notShake) {
          var ele_now = box_now.eles[box_now.curIndex];
          var dom_now = $$(ele_now.htmlEleId);
          if (dom_now) {
            setShakeAnimation(dom_now, dir);
          }
        }
      }
    },

    ok: function () {
      this.okEvent();
      if (!!this.boxes[this.curBoxId]) {
        this.boxes[this.curBoxId].ok();
      }
    },

    del: function () {
      this.delEvent();
    },

    goBack: function (enforce) {
      this.backEvent();
      if (!this.backFlag && enforce != -1) {
        return;
      }
      var curPageUrl = Util.getStore("lastUrl");
      var urlArray = curPageUrl.split("|");
      urlArray.pop();
      var pageUrl = urlArray.join("|");
      Util.setStore("lastUrl", pageUrl);
      if (!!this.backUrl) {
        window.location = this.backUrl;
      }
    },

    pageTurn: function (num, boxId) {
      var tempBox = this.boxes[boxId === undefined ? this.curBoxId : boxId];
      if (!!tempBox) {
        tempBox.pageTurn(num);
      }
    },

    changeFocus: function (boxId, index) {
      var tempBox = this.boxes[this.curBoxId];
      tempBox.changeFocus(tempBox.curIndex, false);
      this.curBoxId = boxId;
      this.boxes[boxId].changeFocus(index, true);
    },

    volumeUp: function () {
      this.volumeUpEvent();
    },

    volumeDown: function () {
      this.volumeDownEvent();
    },

    volumeMute: function () {
      this.volumeMuteEvent();
    },

    utility: function () {
      this.utilityEvent();
    },

    goHomePage: function () {
      this.goHomePageEvent();
    },
  };
  window.Wrapper = Wrapper;
})(window);
(function (window, undefined) {
  String.prototype.replaceAll = function (s1, s2) {
    return this.replace(new RegExp(s1, "gm"), s2);
  };

  function isLocalStorageNameSupported(localStorageName) {
    try {
      if (localStorageName in window && window[localStorageName]) {
        return true;
      }
      return false;
    } catch (err) {
      return false;
    }
  }
  var Util = {
    localStoreSupport: isLocalStorageNameSupported("localStorage"),
    changeURLArg: function (url, arg, arg_val) {
      var pattern = arg + "=([^&]*)";
      var replaceText = arg + "=" + arg_val;
      if (url.match(pattern)) {
        var tmp = "/(" + arg + "=)([^&]*)/gi";
        tmp = url.replace(eval(tmp), replaceText);
        return tmp;
      } else {
        if (url.match("[?]")) {
          return url + "&" + replaceText;
        } else {
          return url + "?" + replaceText;
        }
      }
      return url + "\n" + arg + "\n" + arg_val;
    },
    removeUrlArg: function (url, arg) {
      var pattern = arg + "=([^&]*)";
      if (url.match(pattern)) {
        var tmp = "/(&" + arg + "=)([^&]*)/g";
        tmp = url.replace(eval(tmp), "");
        return tmp;
      }
      return url;
    },
    getSliceList: function (lists, curPage, pageSize) {
      var start = (curPage - 1) * pageSize;
      var end = curPage * pageSize;
      return lists.slice(start, end);
    },

    getQueryString: function (name, url) {
      var _url = url || window.location;
      var reg = new RegExp("(^|&)" + name + "=([^&]*)(&|$)");
      var r = _url.search.substr(1).match(reg);
      if (r !== null) return decodeURIComponent(r[2]);
      return null;
    },

    getUrlString: function (name, url) {
      var _url = url || window.location;
      var reg = new RegExp("(^|&)" + name + "=([^&]*)(&|$)");
      var r = _url.split("?")[1].match(reg);
      if (r !== null) return decodeURIComponent(r[2]);
      return null;
    },

    getPageName: function (url) {
      var tempUrl = url || window.location.href;
      var tempCurPageName = tempUrl.split("?")[0];
      // var tempCurPageName = tempCurPageStr.substring(
      //   0,
      //   tempCurPageStr.lastIndexOf(".")
      // );
      if (tempCurPageName.indexOf("-") > -1) {
        tempCurPageName = tempCurPageName.replaceAll("-", "");
      }
      return tempCurPageName;
    },

    getByteLength: function (str) {
      if (!!str) {
        if (str.constructor != String) {
          str = str.toString();
        }
      } else {
        return 0;
      }
      var byteLen = 0,
        len = str.length;
      if (str) {
        for (var i = 0; i < len; i++) {
          if (str.charCodeAt(i) > 255) {
            byteLen += 2;
          } else {
            if (str.charCodeAt(i) === 119 || str.charCodeAt(i) === 109 || str.charCodeAt(i) === 87 || str.charCodeAt(i) === 77) {
              byteLen += 2;
            } else {
              byteLen++;
            }
          }
        }
        return byteLen;
      }
      return 0;
    },

    /**
     * 获取字符串真实长度,中文字符算2长度
     * @param {string} str 字符串
     */
    getStrRealLen: function (str) {
      if (typeof str != "string" || str.length == 0) return 0;
      var len = 0;
      var strLen = str.length;
      for (var i = 0; i < strLen; i++) {
        a = str.charAt(i);
        len++;
        if (escape(a).length > 4) {
          //中文字符的长度经编码之后大于4
          len++;
        }
      }
      return len;
    },

    /**截取字符串,中文字符算2长度
     * @param {string} str 截取前字符串
     * @param {number} len 截取长度,中文字符算2长度
     * @param {boolean} isSuffix 是否加省略号，默认不加
     */
    getCutedStr: function (str, len, isSuffix) {
      if (typeof str != "string" || str.length == 0) return "";
      var realLen = this.getStrRealLen(str);
      if (realLen <= len) {
        return str;
      } else {
        var str_length = 0;
        var str_cut = new String();
        var str_len = str.length;
        if (isSuffix) len -= 3;
        for (var i = 0; i < str_len; i++) {
          var a = str.charAt(i);
          str_length++;
          if (escape(a).length > 4) {
            //中文字符的长度经编码之后大于4
            str_length++;
          }
          str_cut = str_cut.concat(a);
          if (str_length >= len) {
            if (isSuffix) {
              str_cut = str_cut.concat("...");
            }
            return str_cut;
          }
        }
        //如果给定字符串小于指定长度，则返回源字符串；
        if (str_length < len) return str;
      }
    },

    completionZero: function (str, zeroStr) {
      if (typeof str !== "string") {
        str = str.toString();
      }
      return zeroStr.substring(0, zeroStr.length - str.length) + str;
    },

    isArray: function (obj) {
      var isArr = Object.prototype.toString.call(obj) === "[object Array]";
      if (!isArr && obj !== null) {
        isArr = obj.constructor == Array;
      }
      return isArr;
    },

    isExist: function (obj) {
      return obj !== null && obj !== undefined && obj !== "" && obj != "null" && obj != "undefined";
    },

    createIframe: function (iframeId, url) {
      var tempIframe = document.getElementById(iframeId);
      if (tempIframe === null) {
        var eIframe = document.createElement("iframe");
        eIframe.id = iframeId;
        eIframe.width = "0px";
        eIframe.left = "0px";
        eIframe.style.display = "none";
        eIframe.src = url;
        if (document.body !== null) {
          document.body.appendChild(eIframe);
        }
      } else {
        tempIframe.src = url;
      }
    },

    delIframe: function (id) {
      var tempObj = document.getElementById(id);
      document.body.removeChild(tempObj);
    },

    createSlideEle: function (id, className, speed, parentNode) {
      var tempEle = eZone.$$(id);
      if (tempEle === null) {
        tempEle = document.createElement("div");
        tempEle.id = id;
        tempEle.className = className;
        tempEle.style.left = "0px";
        tempEle.style.top = "0px";
        tempEle.style.width = "0px";
        tempEle.style.height = "0px";
        tempEle.style.display = "none";
        tempEle.style.transitionDuration = speed;
        parentNode = parentNode || document.body;
        if (parentNode !== null) {
          parentNode.appendChild(tempEle);
        }
      }
      return tempEle;
    },

    ajax: function () {
      var type = arguments[0] || "",
        url = arguments[1] || "",
        callBack = arguments[2] || "",
        failCallBack = arguments[3] || function () {},
        content = arguments[4] || "",
        beforeSend = arguments[5] || function () {},
        params = arguments[6] || "",
        xmlhttp;
      if (window.XMLHttpRequest) {
        xmlhttp = new XMLHttpRequest();
      } else {
        xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
      }
      // var isXmlResponse = false;
      // if(type.indexOf('_XML') != -1){
      //   type = type.replace('_XML', '')
      //   isXmlResponse = true;
      // }
      xmlhttp.onreadystatechange = function () {
        if (xmlhttp.readyState == 4) {
          if (/2\d{2}/.test(xmlhttp.status)) {
            if (typeof callBack === "function") {
              callBack(xmlhttp.responseText, params, xmlhttp);
            }
          } else if (/[45]\d{2}/.test(xmlhttp.status) || xmlhttp.status == 0) {
            //前后端状态码统一的处理
            //当前版本后端使用区分业务请求结果的不是http状态码 使用请求体内部的code来实现区分
            // 如 乐豆不足，返回 http=500 data.code=1
            //业务状态码 0正常 1异常 400频繁
            try {
              var _res = JSON.parse(xmlhttp.responseText);
              if (_res.code != undefined) {
                if (typeof callBack === "function") {
                  callBack(xmlhttp.responseText, params, xmlhttp);
                }
              } else {
                if (typeof failCallBack === "function") {
                  failCallBack(xmlhttp.responseText, params);
                }
              }
            } catch (e) {
              if (typeof failCallBack === "function") {
                failCallBack(xmlhttp.responseText, params);
              }
            }
          }
        }
      };
      var ajax_type = "";
      if (type == "JSON_POST") {
        ajax_type = "POST";
      } else {
        ajax_type = type;
      }
      xmlhttp.open(ajax_type, url, true);
      beforeSend && beforeSend(xmlhttp);
      //处理超时
      if (params.timeout) {
        xmlhttp.timeOutTimer = window.setTimeout(function () {
          console.log("ajax timeout!");
          window.clearTimeout(xmlhttp.timeOutTimer);
          params.timeoutcallBack && params.timeoutcallBack;
          xmlhttp.abort();
        }, params.timeout);
      }
      if (type === "GET" || type === "DELETE") {
        xmlhttp.send();
        e = new Date();
      } else if (type === "POST" || type === "JSON_POST") {
        // xmlhttp.withCredentials = true;
        if (type === "JSON_POST") {
          xmlhttp.setRequestHeader("Content-Type", "application/json");
        } else {
          xmlhttp.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
        }
        xmlhttp.send(content);
      }
      return xmlhttp;
    },

    setCookie: function (key, val) {
      var Days = 7;
      var exp = new Date();
      exp.setTime(exp.getTime() + Days * 24 * 60 * 60 * 1000);
      document.cookie = key + "=" + escape(val) + ";expires=" + exp.toGMTString() + ";path=/";
    },

    getCookie: function (key) {
      var arr = null;
      if (document.cookie !== null && document.cookie.length > 0) {
        arr = document.cookie.match(new RegExp("(^| )" + key + "=([^;]*)(;|$)"));
      }
      if (arr !== null) {
        return unescape(arr[2]);
      }
      return null;
    },

    delCookie: function (key) {
      var date = new Date();
      date.setTime(date.getTime() - 10000);
      document.cookie = key + "=;expires=" + date.toGMTString() + ";path=/";
    },

    /**
     * 存储到localstorage
     * @param key
     * @param value
     */
    setStore: function (key, value) {
      if (this.localStoreSupport) {
        if (typeof value === "object") {
          try {
            value = JSON.stringify(value);
          } catch (e) {
            return null;
          }
        }
        window.localStorage.setItem(key, value);
      } else {
        return this.setCookie(key, value);
      }
    },

    /**
     * 根据key获取localstorage中的数据
     * @param key {String}
     * @param deleteTag {Boolean} 是否删除的标志， true: 删除
     * @returns {null}
     */
    getStore: function (key) {
      var storage = window.localStorage;
      if (this.localStoreSupport) {
        var value = storage.getItem(key);
        if (value && value.indexOf("{") == 0) {
          try {
            return JSON.parse(value);
          } catch (e) {
            return value;
          }
        }
        return value;
      } else {
        return this.getCookie(key);
      }
    },

    getAllStore: function () {
      var storage = window.localStorage;
      if (this.localStoreSupport) {
        var len = storage.length; // 获取长度
        var arr = new Array(); // 定义数据集
        for (var i = 0; i < len; i++) {
          // 获取key 索引从0开始
          var getKey = storage.key(i);
          // 获取key对应的值
          var getVal = storage.getItem(getKey);
          // 放进数组
          arr[i] = {
            key: getKey,
            val: getVal,
          };
        }
        return arr;
      }
    },

    delStore: function (key) {
      var storage = window.localStorage;
      if (this.localStoreSupport) {
        storage.removeItem(key);
      } else {
        this.delCookie(key);
      }
    },

    delAllStore: function () {
      var storage = window.localStorage;
      if (this.localStoreSupport) {
        storage.clear();
      }
    },

    animate: function (elem, options) {
      var requestId;
      var change = {
        leftstart: null,
        leftend: null,
        topstart: null,
        topend: null,
      };

      if (options.left != undefined && !isNaN(elem.offsetLeft)) {
        change.leftstart = parseInt(elem.offsetLeft);
        change.leftend = options.left;
      }
      if (options.top != undefined && !isNaN(elem.offsetTop)) {
        change.topstart = parseInt(elem.offsetTop);
        change.topend = options.top;
      }

      var createTime = function () {
        return +new Date();
      };
      var startTime = createTime();

      function render() {
        var remaining = Math.max(0, startTime + options.duration - createTime());
        var temp = remaining / options.duration || 0;
        var percent = 1 - temp;

        var setAttr = function () {
          if (change.leftstart !== null && change.leftend !== null) {
            elem.style.left = (change.leftend - change.leftstart) * percent + change.leftstart + "px";
          }
          if (change.topstart !== null && change.topend !== null) {
            elem.style.top = (change.topend - change.topstart) * percent + change.topstart + "px";
          }
        };
        if (percent === 1) {
          setAttr();
          if (requestId) {
            window.cancelAFrame(requestId);
          }
        } else {
          setAttr();
          requestId = window.requestAFrame(render);
        }
      }

      window.requestAFrame = (function () {
        return (
          window.requestAnimationFrame ||
          window.webkitRequestAnimationFrame ||
          window.mozRequestAnimationFrame ||
          window.oRequestAnimationFrame ||
          function (callback) {
            return window.setTimeout(callback, 1000 / 60);
          }
        );
      })();

      window.cancelAFrame = (function () {
        return (
          window.cancelAnimationFrame ||
          window.webkitCancelAnimationFrame ||
          window.mozCancelAnimationFrame ||
          window.oCancelAnimationFrame ||
          function (id) {
            window.clearTimeout(id);
          }
        );
      })();

      if ((change.leftend != undefined && change.leftstart != change.leftend) || (change.topend != undefined && change.topstart != change.topend)) requestId = window.requestAFrame(render);
    },
  };
  window.Util = Util;
})(window);
// 信号相关 - 处理长按
(function (window, undefined) {
  window.SIGN = {
    // 使用模式 0不使用 1全局使用 2特殊按键使用(CHECK_KEY)
    MODE: 0,
    CHECK_KEY: null,
    // 最后一次信号名称
    LAST_SIGN: null,
    // 最后一次信号时间
    LAST_TIME: new Date().getTime(),
    // 第一次判定的偏移时间
    OFFSET_TIME: 600,
    // 连续信号的单个信号间断判定的最长时间（间距信号超过视为独立信号）
    ONCE_TIME: 100,
    // 连续信号判定的最短时间（长按一秒 判定为长按信号）
    ALL_TIME: 1000,
    // 当前持续时间
    NOW_TIME: 0,
    // 处理标志  0非连续 1持续信号(未达到处理量) 2持续信号(已达到处理量[此状态持续到连续信号结束的下一次信号发起])
    FLAG: 0,
    // 定时器
    TIMER: null,
  };
  window.SIGN.TODO = function (key, todo) {
    var now = new Date().getTime();
    var offset = now - window.SIGN.LAST_TIME;
    //最后一次信号判定
    if (window.SIGN.LAST_SIGN === key && offset <= window.SIGN.ONCE_TIME) {
      if (window.SIGN.FLAG == 0) {
        window.SIGN.FLAG = 1;
      }
      console.log("连续" + offset);
      //连续
      clearTimeout(window.SIGN.TIMER);
      window.SIGN.NOW_TIME += offset;
      if (window.SIGN.NOW_TIME >= window.SIGN.ALL_TIME) {
        if (window.SIGN.FLAG === 1) {
          window.SIGN.FLAG = 2;
          console.log("检测到长按事件");
          todo();
        } else {
          console.log("已处理");
        }
      } else {
        window.SIGN.TIMER = setTimeout(function () {
          console.log("连续长时间未续，处理为非连续");
          window.SIGN.NOW_TIME = 0;
          window.SIGN.FLAG = 0;
          todo();
        }, window.SIGN.ONCE_TIME);
        console.log("连续信号持续时间: " + window.SIGN.NOW_TIME);
      }
    } else {
      console.log("非连续" + offset);
      //非连续
      window.SIGN.NOW_TIME = 0;
      window.SIGN.FLAG = 0;
      clearTimeout(window.SIGN.TIMER);
      window.SIGN.TIMER = setTimeout(function () {
        if (window.SIGN.FLAG == 0) {
          console.log("非连续的延迟处理");
          todo();
        }
      }, window.SIGN.OFFSET_TIME);
    }
    window.SIGN.LAST_TIME = now;
    window.SIGN.LAST_SIGN = key;
  };
})(window);
(function (window, undefined) {
  var Control = {
    grabEvent: function (event, extraVal) {
      var _e = event || window.event;
      var key_code = "";
      if (typeof _e == "object") {
        key_code = _e.keyCode || _e.which || _e.charCode;
      } else {
        key_code = _e;
      }
      if (Wrapper.keyPressLock) {
        return;
      }

      var grabEventTodo = function () {
        var KEY_AV_BACK = 283;
        var KEY_BACK = 8;
        var KEY_OK = 13;
        var KEY_PAGEUP = 33;
        var KEY_PAGEDOWN = 34;
        var KEY_LEFT = 37;
        var KEY_UP = 38;
        var KEY_RIGHT = 39;
        var KEY_DOWN = 40;

        var KEY_0 = 48;
        var KEY_1 = 49;
        var KEY_2 = 50;
        var KEY_3 = 51;
        var KEY_4 = 52;
        var KEY_5 = 53;
        var KEY_6 = 54;
        var KEY_7 = 55;
        var KEY_8 = 56;
        var KEY_9 = 57;

        var KEY_VOLUP = 259;
        var KEY_VOLDOWN = 260;
        var KEY_MUTE = 261;

        var KEY_EVENT = 768;
        window.initTimerGoToFull && window.initTimerGoToFull();

        switch (key_code) {
          case KEY_0:
          case KEY_1:
          case KEY_2:
          case KEY_3:
          case KEY_4:
          case KEY_5:
          case KEY_6:
          case KEY_7:
          case KEY_8:
          case KEY_9:
            Wrapper.numType(key_code - KEY_0);
            break;
          case 87:
          case 119:
          case KEY_UP:
            Wrapper.pressKey_dir_event(1);
            Wrapper.move(0);
            break;
          case 65:
          case 97:
          case KEY_LEFT:
            Wrapper.pressKey_dir_event(2);
            Wrapper.move(1);
            break;
          case 83:
          case 115:
          case KEY_DOWN:
            Wrapper.pressKey_dir_event(3);
            Wrapper.move(2);
            break;
          case 68:
          case 100:
          case KEY_RIGHT:
            Wrapper.pressKey_dir_event(4);
            Wrapper.move(3);
            break;
          case KEY_OK:
            Wrapper.ok();
            break;
          case 32:
          case 340: //宁夏有线Linux机顶盒返回键键值
          case KEY_BACK:
          case KEY_AV_BACK:
            Wrapper.goBack();
            return 1;
            break;
          case 280:
          case 287:
            Wrapper.del();
            break;
          case KEY_PAGEUP:
            Wrapper.pageTurn(-1);
            break;
          case KEY_PAGEDOWN:
            Wrapper.pageTurn(1);
            break;
          case KEY_VOLUP:
          case 595:
            Wrapper.volumeUp();
            break;
          case KEY_VOLDOWN:
          case 596:
            Wrapper.volumeDown();
            break;
          case KEY_MUTE:
          case 597:
            Wrapper.volumeMute();
            break;
          case KEY_EVENT:
            Wrapper.utility();
            break;
          case 513:
            Wrapper.goHomePage();
            break;
          default:
            Wrapper.defaultKeyEvent(key_code);
            break;
        }
        // Wrapper.keyPressLock = true;
        // window.onkeydownTimer = window.setTimeout(function () {
        //   Wrapper.keyPressLock = false;
        // }, 100);
      };

      if (window.SIGN.MODE === 1) {
        window.SIGN.TODO(key_code, grabEventTodo);
      } else if (window.SIGN.MODE === 2 && window.SIGN.CHECK_KEY === key_code) {
        window.SIGN.TODO(key_code, grabEventTodo);
      } else {
        grabEventTodo();
      }
    },

    bindKeydown: function () {
      document.onkeydown = this.grabEvent;
    },

    bindKeypress: function () {
      document.onkeypress = this.grabEvent;
    },

    bindIrkeypress: function () {
      document.onirkeypress = this.grabEvent;
    },

    bindSystemevent: function () {
      document.onsystemevent = this.grabEvent;
    },
  };
  window.Control = Control;
  Control.bindKeydown();
})(window);
/**
 * 统一节点操作,链式调用
 * @author yqling by 2022.05
 *
 * 属性:
 *    $('selector').node          原始节点
 * 方法:
 *    $('selector').getNode       获取原始节点
 *    $('selector').hasClass      是否包含class
 *    $('selector').addClass      增加class
 *    $('selector').removeClass   移除class
 *    $('selector').hide          隐藏
 *    $('selector').show          显示
 *    $('selector').css           设置样式
 *    $('selector').scrollTop     设置或获取scrollTop
 *    $('selector').scrollLeft    设置或获取scrollLeft
 *    $('selector').attr          设置或获取属性
 *    $('selector').html          设置或获取HTML
 *    $('selector').text          设置或获取文本
 *    $('selector').val           设置或获取value
 *    $('selector').append        追加到本身
 *    $('selector').appendTo      本身追加打节点
 *    $('selector').remove        移除本身
 *    $('selector').clone         克隆本身
 * 示例：
 *    原始Node转Dom包装
 *        $(dom)
 *    Dom包装转原始Node
 *        dom.getNode()
 */

(function (window, undefined) {
  var Dom = function (selector) {
    //查找链
    this.selector = selector;
    //原始节点
    this.node = (function (selector) {
      //暂时只使用id查询
      return document.getElementById(selector);
    })(selector);
  };

  //获取原始节点
  Dom.prototype.getNode = function () {
    return this.node;
  };

  //设置class
  Dom.prototype.class = function (className) {
    if (className) {
      this.node.className = className;
      return this;
    } else {
      return this.node.className;
    }
  };

  //是否包含class
  Dom.prototype.hasClass = function (className) {
    return this.node.className.match(new RegExp("(\\s|^)" + className + "(\\s|$)"));
  };

  //增加class，className可传多个空格隔开
  Dom.prototype.addClass = function (className) {
    var _arr = className.split(" ");
    if (_arr.length > 1) {
      for (var i = 0; i < _arr.length; i++) {
        this.addClass(_arr[i]);
      }
    } else {
      if (!this.hasClass(className)) {
        if (this.node.className == "") {
          this.node.className = className;
        } else {
          this.node.className += " " + className;
        }
      }
    }
    return this;
  };

  //移除class，className可传多个空格隔开
  Dom.prototype.removeClass = function (className) {
    if (className === undefined) {
      this.node.className = "";
    } else {
      var _arr = className.split(" ");
      if (_arr.length > 1) {
        for (var i = 0; i < _arr.length; i++) {
          this.removeClass(_arr[i]);
        }
      } else {
        if (this.hasClass(className)) {
          var reg = new RegExp("(\\s|^)" + className + "(\\s|$)");
          this.node.className = this.node.className.replace(reg, " ").trim();
        }
      }
    }
    return this;
  };

  //存在删除 否则添加 样式名
  Dom.prototype.toggleClass = function (className) {
    if (className !== undefined) {
      if (this.hasClass(className)) {
        this.removeClass(className);
      } else {
        this.addClass(className);
      }
    }
    return this;
  };

  //控制隐藏
  Dom.prototype.hide = function () {
    this.css("display", "none");
    return this;
  };

  //控制显示
  Dom.prototype.show = function () {
    this.css("display", "block");
    return this;
  };

  //设置或获取css
  Dom.prototype.css = function (key, value) {
    if (typeof key === "object") {
      //对象设置方式
      for (var _k in key) {
        console.log(_k, key[_k]);
        this.css(_k, key[_k]);
      }
    } else {
      if (value == undefined) {
        //获取css
        return this.node.style[key];
      } else {
        //普通键值对
        this.node.style[key] = value;
      }
    }
    return this;
  };

  //设置或获取width
  Dom.prototype.width = function (numb) {
    if (numb === undefined) {
      return this.node.offsetWidth;
    } else {
      if (/^[+-]?\d*$/.test(numb)) {
        this.css("width", numb + "px");
      } else {
        this.css("width", numb);
      }
      return this;
    }
  };

  //设置或获取height
  Dom.prototype.height = function (numb) {
    if (numb === undefined) {
      return this.node.offsetHeight;
    } else {
      if (/^[+-]?\d*$/.test(numb)) {
        this.css("height", numb + "px");
      } else {
        this.css("height", numb);
      }
      return this;
    }
  };

  //设置或获取left
  Dom.prototype.left = function (numb) {
    if (numb === undefined) {
      return this.css("left");
    } else {
      if (/^[+-]?\d*$/.test(numb)) {
        this.css("left", numb + "px");
      } else {
        this.css("left", numb);
      }
      return this;
    }
  };

  //设置或获取top
  Dom.prototype.top = function (numb) {
    if (numb === undefined) {
      return this.css("top");
    } else {
      if (/^[+-]?\d*$/.test(numb)) {
        this.css("top", numb + "px");
      } else {
        this.css("top", numb);
      }
      return this;
    }
  };

  //获取offsetLeft 默认深度
  Dom.prototype.offsetLeft = function (root, deep) {
    if (root === undefined) {
      root = document.body;
    }
    if (deep === undefined) {
      deep = true;
    }
    if (ele == root) {
      return 0;
    }
    return ele.offsetLeft + (deep ? this.offsetLeft(ele.offsetParent, root, deep) : 0);
  };

  //获取offsetTop 默认深度
  Dom.prototype.offsetTop = function (ele, root, deep) {
    if (root === undefined) {
      root = document.body;
    }
    if (deep === undefined) {
      deep = true;
    }
    if (ele == root) {
      return 0;
    }
    return ele.offsetTop + (deep ? this.offsetTop(ele.offsetParent, root, deep) : 0);
  };

  //设置或获取scrollTop
  Dom.prototype.scrollTop = function (value) {
    if (value === undefined) {
      return this.node.scrollTop;
    }
    this.node.scrollTop = value;
    return this;
  };

  //设置或获取scrollLeft
  Dom.prototype.scrollLeft = function (value) {
    if (value === undefined) {
      return this.node.scrollLeft;
    }
    this.node.scrollLeft = value;
    return this;
  };

  //设置或获取attr
  Dom.prototype.attr = function (key, value) {
    if (value === undefined) {
      return this.node.getAttribute(key);
    }
    this.node.setAttribute(key, value);
    return this;
  };

  //设置或获取html
  Dom.prototype.html = function (html) {
    if (html === undefined) {
      return this.node.innerHTML;
    }
    this.node.innerHTML = html;
    return this;
  };

  //设置或获取text
  Dom.prototype.text = function (text) {
    if (text === undefined) {
      return this.node.innerText;
    }
    this.node.innerText = text;
    return this;
  };

  //设置或获取val
  Dom.prototype.val = function (val) {
    if (val === undefined) {
      return this.node.value;
    }
    this.node.value = val;
    return this;
  };

  //追加元素
  Dom.prototype.append = function (dom) {
    this.node.appendChild(dom);
    return this;
  };

  //追加到另一元素
  Dom.prototype.appendTo = function (dom) {
    dom.appendChild(this.node);
    return this;
  };

  //移除本身
  Dom.prototype.remove = function () {
    var _parent = this.node.parentNode;
    if (_parent) {
      _parent.removeChild(this.node);
    }
    return this;
  };

  //父级元素
  Dom.prototype.parent = function () {
    return $(this.node.parentNode);
  };

  //克隆本身，返回克隆的原始节点，deep为是否深拷贝
  Dom.prototype.clone = function (deep) {
    return this.node.cloneNode(deep);
  };

  //添加事件句柄
  var _arr_event_name = [
    "abort",
    "blur",
    "change",
    "click",
    "dblclick",
    "error",
    "focus",
    "keydown",
    "keypress",
    "keyu",
    "load",
    "mousedown",
    "mousemov",
    "mouseout",
    "mouseover",
    "mouseup",
    "reset",
    "resize",
    "select",
    "submit",
    "unload",
    "scroll",
  ];
  for (var i = 0; i < _arr_event_name.length; i++) {
    var _event_name = _arr_event_name[i];
    (function (_event_name) {
      Dom.prototype[_event_name] = function (_func) {
        var _real_event_nama = "on" + _event_name;
        if (_func === undefined) {
          //不能更改this  因为原onclick绑定时处理this为当时的情况下
          this.node[_real_event_nama] && this.node[_real_event_nama]();
        } else {
          //更改this绑定为包装对象
          this.node[_real_event_nama] = _func.bind(this);
        }
        return this;
      };
    })(_event_name);
  }

  //工厂模式
  window.$ = function (selector) {
    if (selector instanceof Node) {
      //Node类型做包装
      selector = selector.id;
    }
    return new Dom(selector);
  };
})(window);
/**
 * 公共弹窗具体实现逻辑
 * @author yqling by 2022.05
 * @param {*} type 弹窗alert 吐司toast
 * @param {*} msg 消息文本
 * @param {*} alwaysShow 保持前端显示
 * @param {*} reset 初始化
 *
 * 依赖css
 */
(function (window, undefined) {
  var MSG = function () {
    this.data = {};
  };

  MSG.prototype.show = function (type, text, alwaysShow, reset) {
    var item = this.data[type];
    if (item == undefined) {
      item = this.data[type] = {};
    }
    if (item.time !== null) {
      window.clearTimeout(item.time);
      item.time = null;
    }
    var _name = "dia-" + type;
    var _dom = document.getElementById(_name);
    if (!_dom) {
      _dom = document.createElement("div");
      _dom.id = _dom.className = _name;
    } else {
      _dom.style.opacity = "1";
    }
    if (reset) {
      _dom.innerHTML = text;
    } else {
      _dom.innerHTML += "<br/>" + text;
    }
    document.body.appendChild(_dom);
    if (!alwaysShow) {
      if (item.time != null) {
        window.clearTimeout(item.time);
        item.time = null;
      }
      item.time = window.setTimeout(function () {
        _dom.style.opacity = "0";
      }, 2000);
    }
  };

  /**
   * EPG弹窗
   * @param {string} msg
   * @param {*} alwaysShow
   * @param {*} reset
   */
  MSG.prototype.alert = function (msg, alwaysShow, reset) {
    this.show("alert", msg, alwaysShow, reset);
  };

  /**
   * EPG吐司
   * @param {*} msg
   * @param {*} alwaysShow
   * @param {*} reset
   */
  MSG.prototype.toast = function (msg, alwaysShow, reset) {
    this.show("toast", msg, alwaysShow, reset);
  };

  window.msg = new MSG();
})(window);
/**
 * 统一本地存储
 * @author yqling by 2022.05
 *
 * 属性:
 *    store.localStoreSupport     检测是否支持localStorage
 * 方法:
 *    store.get           获取一个localStorage
 *    store.set           设置一个localStorage
 *    store.del           清除一个localStorage
 *    store.delAll        清除所有localStorage
 *    store.getCookie     获取一个Cookie
 *    store.setCookie     设置一个Cookie
 *    store.delCookie     删除一个Cookie
 */

(function (window, undefined) {
  var Store = function () {
    //是否支持本地缓存
    this.localStoreSupport = (function (localStorageName) {
      try {
        if (localStorageName in window && window[localStorageName]) {
          return true;
        }
        return false;
      } catch (err) {
        return false;
      }
    })("localStorage");
  };

  /**
   * 设置storage
   * @param {*} key 键
   * @param {*} val 值
   * @returns this
   */
  Store.prototype.set = function (key, val) {
    if (this.localStoreSupport) {
      if (typeof val === "object") {
        try {
          val = JSON.stringify(val);
        } catch (e) {}
      }
      window.localStorage.setItem(key, val);
      return this;
    } else {
      this.setCookie(key, val);
      return this;
    }
  };

  /**
   * 获取storage
   * @param {*} key 键
   * @returns this
   */
  Store.prototype.get = function (key) {
    if (this.localStoreSupport) {
      var val = window.localStorage.getItem(key);
      // if (val && (val.indexOf("{") == 0 || val.indexOf("[") == 0)) {
      try {
        return JSON.parse(val);
      } catch (e) {
        return val;
      }
      // }
      // return val;
    } else {
      return this.getCookie(key);
    }
  };

  //获取所有storage
  Store.prototype.all = function () {
    if (this.localStoreSupport) {
      var len = window.localStorage.length;
      var res = {};
      for (var i = 0; i < len; i++) {
        var key = window.localStorage.key(i);
        res[key] = window.localStorage.getItem(key);
      }
      return res;
    } else {
      return {};
    }
  };

  //清除storage
  Store.prototype.del = function (key) {
    if (this.localStoreSupport) {
      window.localStorage.removeItem(key);
    } else {
      this.delCookie(key);
    }
  };

  //清除所有storage
  Store.prototype.clear = function () {
    if (this.localStoreSupport) {
      window.localStorage.clear();
    }
  };

  //设置cookie
  Store.prototype.setCookie = function (key, val, day) {
    var day = day || 7;
    var exp = new Date();
    exp.setTime(exp.getTime() + day * 24 * 60 * 60 * 1000);

    if (typeof val === "object") {
      try {
        val = JSON.stringify(val);
      } catch (e) {}
    }

    document.cookie = key + "=" + escape(val) + ";expires=" + exp.toGMTString() + ";path=/";
  };

  //获取cookie
  Store.prototype.getCookie = function (key) {
    var arr = null;
    if (document.cookie !== null && document.cookie.length > 0) {
      arr = document.cookie.match(new RegExp("(^| )" + key + "=([^;]*)(;|$)"));
    }
    if (arr !== null) {
      var result = unescape(arr[2]);
      try {
        return JSON.parse(result);
      } catch (e) {
        return result;
      }
    }
    return null;
  };

  //清除cookie
  Store.prototype.delCookie = function (key) {
    this.setCookie(key, "", -1);
  };

  window.store = new Store();
})(window);
/**
 * 统一网络请求
 * @author yqling by 2022.05
 * 属性:
 *    http.baseURL           统一接口前缀路径（例外请求用http.ajax）
 *    http.defaultOptions   默认请求参数
 * 方法:
 *    http.ajax             发起一个ajax请求
 *    http.request          带默认值的ajax请求(url附加http.baseURL)
 *    http.get              带默认值的ajax请求(type=GET)
 *    http.post             带默认值的ajax请求(type=POST)
 *    http.requestIntercept   请求拦截器
 *    http.responseIntercept    响应拦截器
 * 示例：
 *    http.baseURL = 'http://www.test.com'
 *    http.get({
 *      url: '/api/qld/prizeBags/user/{userId}',
 *      params: {
 *        userId: 1000,
 *        regionCode: 1
 *      },
 *      success: function () { },
 *      error: function () { }
 *    });
 *    ajax(get)请求: http://www.test.com/api/qld/prizeBags/user/1000?regionCode=1
 */

(function (window, undefined) {
  var HTTP = function () {
    //url接口
    this.interface = {
      xxx1: "/aaa/bbb/ccc",
      xxx2: "/aaa/bbb/{ccc}",
    };
    //统一前缀路径（使用前必须配置）
    this.baseURL = (window.config && window.config.NET_ATTR) || "";
    this.defaultOptions = {
      type: "GET",
      url: "",
      baseURL: this.baseURL,
      success: function () {}, // 成功请求响应 参数: 请求文本, http状态码
      error: function () {}, // 失败请求响应 参数: 请求文本, http状态码或特殊状态说明(拦截、超时等)
      beforeSend: function () {}, // 正式发送请求前触发 可用于loading效果
      params: {}, // 请求数据参数
      dataType: "JSON", // 响应数据格式，JSON、XML、TXT等
      timeout: 0, // 超时时间，为0则永不超时，超时后回调 error(null, 'TIMEOUT')
    };
  };

  /**
   * 设置baseURL
   * @param {*} url
   */
  HTTP.prototype.setBaseURL = function (url) {
    this.defaultOptions.baseURL = this.baseURL = url;
  };

  //处理ajax
  HTTP.prototype.ajax = function (options) {
    var xmlhttp;
    if (window.XMLHttpRequest) {
      xmlhttp = new XMLHttpRequest();
    } else {
      xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
    }
    if (options.header) {
      var len = options.header.length;
      for (var i = 0; i < len; i++) {
        var opt = options.header[i];
        xmlhttp.setRequestHeader(opt.key, opt.val);
      }
    }
    var _this = this;
    xmlhttp.onreadystatechange = function () {
      if (xmlhttp.readyState == 4) {
        var _is_success = /2\d{2}/.test(xmlhttp.status);
        var _is_error = /[45]\d{2}/.test(xmlhttp.status) || xmlhttp.status == 0;
        if (_is_success || _is_error) {
          //响应拦截处理
          if (_this.responseIntercept(options, xmlhttp)) {
            if (_is_success) {
              options.success && options.success(xmlhttp.responseText, xmlhttp.status);
            } else {
              options.error && options.error(xmlhttp.responseText, xmlhttp.status);
            }
          }
        }
      }
    };
    xmlhttp.open(options.type, options.url, true);
    options.beforeSend && options.beforeSend(xmlhttp);
    // 定义超时处理
    if (options.timeout) {
      options.timer = window.setTimeout(function () {
        window.clearTimeout(options.timer);
        xmlhttp.abort();
        options.error(null, "TIMEOUT");
      }, options.timeout);
    }
    if (options.type === "GET" || options.type === "DELETE") {
      xmlhttp.send();
    } else if (options.type === "POST") {
      if (options.dataType.toUpperCase() == "JSON") {
        xmlhttp.setRequestHeader("Content-Type", "application/json");
      } else {
        xmlhttp.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
      }
      xmlhttp.send(JSON.stringify(options.params));
    }
    return xmlhttp;
  };

  //ajax请求分发
  HTTP.prototype.request = function (options) {
    options = tool.objectAssign({}, this.defaultOptions, options);
    //默认get请求
    options.type = options.type ? options.type.toUpperCase() : "GET";
    //请求拦截处理
    if (this.requestIntercept(options)) {
      return this.ajax(options);
    } else {
      options.error(null, "REQUEST INTERCEPT");
      return null;
    }
  };

  //get请求
  HTTP.prototype.get = function (options) {
    options.type = "GET";
    return this.request(options);
  };

  //post请求
  HTTP.prototype.post = function (options) {
    options.type = "POST";
    return this.request(options);
  };

  //请求拦截器  返回false代表拦截，后续不做正常流程
  HTTP.prototype.requestIntercept = function (options) {
    // eg: 拦截示例
    if (/test/.test(options.url)) {
      // 拦截url包含test的请求
      return false;
    }
    //设置RESTful风格api的参数
    options.url = this.getRESTfulUrl(options.url, options.params);
    //get方式请求拼接参数到url
    if (options.type == "GET" || options.postType == "url") {
      options.url += this.buildUrlParams(options.params);
    }
    //设置公共URL
    if (!/^https?:\/\//i.test(options.url)) {
      if (options.url.indexOf("../") == -1) {
        options.url = options.baseURL + options.url;
      }
    }
    return true;
  };

  //响应拦截器  返回false代表拦截，后续不做正常流程
  HTTP.prototype.responseIntercept = function (options, xmlhttp) {
    // eg: 拦截示例
    if (options.dataType.toUpperCase() == "JSON") {
      // 趣乐逗(不止此项目)的特殊处理(无业务状态码) 以及预转换JSON
      var res_data = null;
      try {
        res_data = JSON.parse(xmlhttp.responseText);
      } catch (err) {
        options.error(null, "CONVERT JSON ERROR");
        return false;
      }
      if (/[45]\d{2}/.test(res_data.code)) {
        options.error(res_data, xmlhttp.status);
      } else {
        options.success(res_data, xmlhttp.status);
      }
      return false;
    } else if (options.dataType.toUpperCase() == "XML") {
      // XML数据格式响应请求
      if (xmlhttp.responseXML) {
        xmlhttp.responseText = xmlhttp.responseXML;
      }
    } else {
      return true;
    }
    return true;
  };

  /**
   * 设置RESTful风格请求的url参数
   * @param {*} url         原url地址附带{key}类似的字符串
   * @param {*} paramsObj   替换的配置对象,{key:value}
   */
  HTTP.prototype.getRESTfulUrl = function (url, paramsObj) {
    var numb = 0; //防止paramsObj[matchText]="{.*?}"等的形式
    while (/{(.*?)}/g.test(url) && ++numb < 99) {
      var matchText = "" + RegExp.$1;
      url = url.replace("{" + matchText + "}", paramsObj[matchText]);
    }
    return url;
  };

  /**
   * 拼接url字符串(get使用)
   * @param {*} params     设置参数集合对象
   */
  HTTP.prototype.buildUrlParams = function (params) {
    var arr = [];
    for (var key in params) {
      if (params.hasOwnProperty(key) && params[key] !== null) {
        arr.push(key + "=" + params[key]);
      }
    }
    return "?" + arr.join("&");
  };

  window.http = new HTTP();
})(window);
/**
  控制台指令集成
 * @author yqling by 2022.05
  9:系统保留
    9526   命令列表
    9527   开启/关闭开发者模式(若不关闭，下次打开apk或切换页面也会保留上次模式)

  8:清除口令
    任意时刻使用直接清除缓存口令防止误操作

  开发者模式：
    每四个数字为一个指令(口令规范为禁止出现8和9)

    4-5:系统业务
    6:信息显示
        6000   系统信息
        6001   用户信息
        6002   网页信息
    7:系统操作
        7000   切换显示/隐藏日志输出窗口
        7001   清除弹窗内容
        7002   刷新页面

  用户模式：
    自定义指令，一般需要处理为四个数字为一个指令
      1-3:一般业务
        1常规业务
        2跳转业务
        3预留

  相关wiki文档 http://132.232.138.176:29080/pages/viewpage.action?pageId=50069592
  依赖 dom.js store.js
  任何公用的都可以加在里面
 */
(function (window, undefined) {
  var CMD = function () {
    this.data = {
      6000: {
        desc: "显示系统信息",
        func: function () {
          //系统信息
          msg.alert("<br/>系统信息:<br/>&nbsp;&nbsp;&nbsp;&nbsp;EPG版本:" + getEpgVersion() + "<br/>&nbsp;&nbsp;&nbsp;&nbsp;APK版本:" + getApkVersion() + "<br/>", true);
        },
      },
      6001: {
        desc: "显示用户信息",
        func: function () {
          //用户信息
          msg.alert("<br/>用户信息:<br/>&nbsp;&nbsp;&nbsp;&nbsp;" + JSON.stringify(user) + "<br/>", true);
        },
      },
      6002: {
        desc: "显示网页信息",
        func: function () {
          //网页信息
          msg.alert("<br/>网页信息:<br/>&nbsp;&nbsp;&nbsp;&nbsp;" + location.href + "<br/>", true);
        },
      },
      7000: {
        desc: "切换显示/关闭弹窗",
        func: function () {
          //切换显示/关闭弹窗
          var _dom = $("dia-alert");
          if (_dom) {
            if (_dom.css("opacity") == "0") {
              _dom.css("opacity", "1");
            } else {
              _dom.css("opacity", "0");
            }
          }
        },
      },
      7001: {
        desc: "清除弹窗内容",
        func: function () {
          //清除弹窗内容
          var _dom = $("dia-alert");
          if (_dom) {
            _dom.html("");
            _dom.css("opacity", "0");
          }
        },
      },
      7002: {
        desc: "刷新页面",
        func: function () {
          //刷新页面
          location.reload();
        },
      },
      7003: {
        desc: "清除页面缓存",
        func: function () {
          //清除页面缓存
          clearAllDIYStore();
        },
      },
      7010: {
        desc: "跳转测试α",
        func: function () {
          loadUrl("http://132.232.138.176:16688/hotel_start/");
        },
      },
      7011: {
        desc: "跳转测试β",
        func: function () {
          loadUrl("http://192.168.31.192:1688/hotel_start/");
        },
      },
      9526: {
        desc: "列出所有命令",
        func: function () {
          var str = "";
          for (var i in cmd.data) {
            var item = cmd.data[i];
            str += i + ":" + item.desc + "<br/>";
          }
          str += "按8清除命令";
          msg.alert(str, true);
        },
      },
      9527: {
        desc: "开启/关闭开发者模式",
        func: function () {
          //开启/关闭开发者模式
          if ((cmd.developer = !cmd.developer)) {
            msg.alert("开发者模式: 已开启", false, true);
            cmd.listen(9526);
          } else {
            msg.alert("开发者模式: 已关闭", false, true);
          }
          store.set("DEVELOPER_MODE", cmd.developer);
        },
      },
    };
    this.buffer = "";
    this.developer = store.get("DEVELOPER_MODE");
  };

  /**
   * 注册一个事件，当前页面有效
   * @param {*} key
   * @param {*} func
   * @returns
   */
  CMD.prototype.set = function (key, params) {
    this.data[key] = params;
    return this;
  };

  // 通用结束句柄
  CMD.prototype.over = function () {};

  CMD.prototype.listen = function (key) {
    if (typeof key == "number") {
      key = "" + key;
    }
    var _func = this.data[key] && this.data[key].func;
    if (key == "9527" || (this.developer && key.length == 4)) {
      _func && _func();
      this.buffer = "";
      cmd.over();
    }
  };

  /**
   * 事件机制，必要时可重写
   * @param {*} numb
   */
  CMD.prototype.todo = function (numb) {
    if (numb == "8") {
      //清除口令缓存
      this.buffer = "";
    }
    this.listen(this.buffer);
  };

  /**
   * 开启句柄、页面存在numTypeEvent可重复调用，绑定事件
   */
  CMD.prototype.start = function () {
    var that = this;
    var func = Wrapper.numTypeEvent;
    Wrapper.numTypeEvent = function (numb) {
      func && func(numb);
      that.buffer += numb;
      that.todo(numb);
    };
    if (that.developer) {
      msg.alert("开发者模式: 已开启(按9527关闭)", false, true);
    }
  };

  window.cmd = new CMD();
  cmd.start();
})(window);
/**
 * 用户信息
 */
 (function (window) {
  var USER = function () {
    this.userInfo = {};
    if (typeof Utility != "undefined" || typeof nativeClient != "undefined") {
      if (typeof nativeClient != "undefined") {
        // nativeClient：我们的apk提供的获取用户信息的对象（湖南环境用的这个）
        if (nativeClient.getDeviceUserInfo) {
          // 软终端获取用户信息
          this.type = "tv";
          this.userInfo = nativeClient.getDeviceUserInfo();
          // alertMsg("----getDeviceUserInfo" + this.userInfo, true);
        } else if (nativeClient.getHnyxUserInfo) {
          // 酒店盒子获取用户信息
          this.type = "stb";
          this.userInfo = nativeClient.getHnyxUserInfo();
          // alertMsg("----getHnyxUserInfo" + this.userInfo, true);
        } else if (nativeClient.getSTBUserInfo) {
          this.type = "gsfs";
          this.userInfo = nativeClient.getSTBUserInfo();
        }
      } else if (typeof Utility != "undefined") {
        // Utility:广电apk提供的获取用户信息的对象（甘肃环境用的这个）
        this.type = "stb";
        if (Utility.getSysInfo) {
          this.userInfo.stbType = Utility.getSysInfo("ro.product.model");
          // alertMsg("----userInfo----" + JSON.stringify(this.userInfo), true);
        }
        this.userInfo.userID = Utility.getUserID();
        // alertMsg("----userInfo.userID----" + Utility.getUserID(), true);
        this.userInfo.stbID = Utility.getStbID();
        // alertMsg("----userInfo.stbID----" + Utility.getStbID(), true);
      } else {
        this.userInfo = {};
      }
      if (typeof this.userInfo == "string") {
        this.userInfo = JSON.parse(this.userInfo);
      }

      if(!this.userInfo){
        this.userInfo = {};
      }

      this.stbIP = this.userInfo.actualIp || config.DEFAULT_STB_IP;
      this.userID = this.userInfo.partnerUserID || this.userInfo.userID || this.userInfo.iptvUserID;
      if (!this.userID && this.type == "stb") {
        this.userID = config.DEFAULT_USER_ID;
      }
      if (this.userID == "dataNameNotExist") {
        this.userID = "";
      }
      this.token = this.userInfo.token || config.DEFAULT_TOKEN;
      this.stbID = this.userInfo.stbID || config.DEFAULT_STB_ID;
      this.mac = this.userInfo.mac;
      if (!this.mac && this.type == "stb") {
        this.mac = config.DEFAULT_MAC;
      }
      this.stbType = this.userInfo.stbType;
      this.userGroup = this.userInfo.userGroup;
      this.areaCode = this.userInfo.areaCode;
      this.countryCode = this.userInfo.countryCode;
      this.cityCode = this.userInfo.cityCode;
      if (this.type == "tv") {
        // 软终端 类型固定为12
        this.stbType_w = 12;
      } else {
        this.stbType_w = this.userInfo.stbType_w;
      }
      this.subProjectId = this.userInfo.subProjectId;
    } else {
      //通过浏览器直接访问的情况
      this.stbIP = config.DEFAULT_STB_IP;
      this.userID = store.get("userID") ? store.get("userID") : config.DEFAULT_USER_ID;
      this.stbID = store.get("stbID") ? store.get("stbID") : config.DEFAULT_STB_ID;
      this.mac = store.get("mac") ? store.get("mac") : config.DEFAULT_MAC;
      this.stbType = config.DEFAULT_STB_TYPE;
      this.userGroup = config.DEFAULT_USER_GROUP;
      this.areaCode = config.DEFAULT_AREA_CODE;
      this.countryCode = config.DEFAULT_COUNTRY_CODE;
      this.cityCode = config.DEFAULT_CITY_CODE;
    }
    var userAuthInfo = {};

    var customerCode = Util.getQueryString("customerCode") || "";
    var customerName = Util.getQueryString("customerName") || "";
    var orgCode = Util.getQueryString("orgCode") || "";
    var orgName = Util.getQueryString("orgName") || "";
    var indexCategoryCode = Util.getQueryString("indexCategoryCode") || "";
    var baseCategoryCode = Util.getQueryString("baseCategoryCode") || "";
    if (
      customerCode &&
      customerName &&
      orgCode &&
      orgName &&
      indexCategoryCode &&
      baseCategoryCode
    ) {
      userAuthInfo = {
        customerCode: customerCode,
        customerName: customerName,
        orgCode: orgCode,
        orgName: orgName,
        indexCategoryCode: indexCategoryCode,
        baseCategoryCode: baseCategoryCode,
      };
    } else {
      userAuthInfo = store.get("userAuthInfo");
    }
    if (userAuthInfo) {
      this.userAuthInfo = userAuthInfo;
    } else {
      this.userAuthInfo = {};
    }
  };

  window.user = new USER();
})(window);

/**
 * 业务鉴权中心
 * @author yqling by 2022.05
 */

(function (window) {
  var BS = function () {};

  BS.prototype.auth = function (params, callBack, failCallBack) {};

  BS.prototype.order = function (params, callBack, failCallBack) {};

  window.BS = new BS();
})(window);
/**
 * 过滤器
 * @author yqling by 2022.05
 * 配合template.js完成页面过滤器
 */
(function (window, undefined) {
  var Filter = function () {};

  Filter.prototype.getPicture = function (url) {
    if (url && url != " ") {
      if (url.indexOf("http://") == -1 && url.indexOf("../") == -1) {
        url = config.IMG_ATTR + url;
      }
      return url;
    }
    return config.IMG_DEFAULT;
  };

  /**
   * 过滤器注册
   * @param {*} name
   * @param {*} func
   */
  Filter.prototype.set = function (name, func) {
    filter[name] = func;
  };

  window.filter = new Filter();
})(window);
/**
 *  模版2.0代码（框架构思）
 * @author yqling by 2022.05
    <div class="item" id="box1_{index}">
      <img class="item_icon" src="{data.icon | getPicture}" />
      <span class="item_text">{data.text}</span>
    </div>
  支持链式调用 若值不存在则为""空值
  支持过滤器，另传入作用域可改变指向
 */
(function (window, undefined) {
  var VIEW = function () {
    this.template = {};
  };

  // 获取todo函数
  var getTodo = function (vals, filter) {
    vals = vals.split(".");
    return function (data, index, id) {
      var result = "";
      if (vals[0] == "index") {
        result = index;
      } else if (vals[0] == "id") {
        result = id;
      } else if (vals[0] == "src") {
        result = "src";
      } else {
        var index = 1;
        if (vals[0] != "data") {
          data = window;
          index = 0;
        }
        try {
          for (; index < vals.length; index++) {
            data = data[vals[index]];
          }
        } catch (e) {
          console.error(e);
          data = "";
        }
        result = data;
      }
      if (filter) {
        // 过滤器
        var scope = window;
        if (window.filter) {
          scope = window.filter;
        }
        try {
          if (scope[filter]) {
            return scope[filter](result);
          } else {
            throw new Error("未实现的过滤器:" + filter);
          }
        } catch (e) {
          console.error(e);
          return result;
        }
      }
      return result;
    };
  };

  // 解析模版 得到处理方法数组
  var getTodos = function (template) {
    var j = 0;
    var todos = [];
    var reg_name = /\{\s*(\S*?)\s*(?:\|\s*(\S*?)\s*)?\}/;
    var arr = null;
    while (j++ < 99) {
      arr = template.match(reg_name);
      if (arr && arr[1]) {
        todos.push({
          name: arr[0],
          func: getTodo(arr[1], arr[2]),
        });
        template = template.replace(arr[0], "");
      } else {
        break;
      }
    }
    return todos;
  };

  // 获取节点代码
  VIEW.prototype.getTemplateHtmls = function (templateName, data, once, id) {
    var template = this.getTemplate(templateName);
    var todos = getTodos(template);
    var htmls = [];
    for (var i = 0; i < data.length; i++) {
      var _data = data[i];
      var rander = template;
      for (var j = 0; j < todos.length; j++) {
        var item = todos[j];
        rander = rander.replace(item.name, item.func(_data, i, id));
      }
      htmls.push(rander);
      once && once(_data);
    }
    return htmls.join("");
  };

  /**
   * 获取模型
   * @param {*} name
   * @returns
   */
  VIEW.prototype.getTemplate = function (name) {
    if (this.template[name] == undefined) {
      this.template[name] = document.getElementById(name).innerHTML;
    }
    return this.template[name];
  };

  /**
   * 自动获取绑定视图
   * @param {*} box
   * @param {*} data
   * @param {*} template
   * @returns
   */
  VIEW.prototype.bindDataView = function (box, data, templateName, mountId, once) {
    if (typeof box == "number") {
      box = Wrapper.boxes[box];
    }
    if (templateName == undefined) {
      templateName = "templateBox" + box.id;
    }
    var htmls = this.getTemplateHtmls(templateName, data, once, box.id);
    if (box.id != null) {
      box.totalEle = data.length;
      box.data = data;
      box.clearEles && box.clearEles();
    }
    // 默认挂载点
    if (mountId == undefined) {
      mountId = "box" + box.id;
    }
    var _dom = document.getElementById(mountId);
    if (_dom) {
      _dom.innerHTML = htmls;
    }
    return htmls;
  };

  window.view = new VIEW();
})(window);
/**
 * 统一通用工具
 * @author yqling by 2022.05
 *
 * 属性:
 *
 * 方法:
 *    tool.urlParam           设置/清除/获取 url参数信息
 *    tool.getPageName        获取当前网页名称
 *    tool.getSliceList       数组切片分页,curPage从1开始
 */

(function (window, undefined) {
  var Tool = function () {};

  //----------------------------------- 页面地址相关
  /**
   * 设置/获取url参数 不改变原字符串
   *   获取当前url的pageSize  tool.urlParam(null, 'pageSize')
   *   设置当前url的pageSize  tool.urlParam(null, 'pageSize', '5')
   *   清除当前url的pageSize  tool.urlParam(null, 'pageSize', null)
   *   或调用具体事件的分发 getUrlParam  setUrlParam  delUrlParam
   * @param {*} url     url参数信息,url不填默认location
   * @param {*} key     必填,键值
   * @param {*} value   value不填代表获取 填非null代表设置（为null代表清除）
   */
  Tool.prototype.urlParam = function (url, key, value) {
    url = url || window.location.href;
    var reg = new RegExp("(^|&|/?)" + key + "=([^&]*)(&|$)");
    var r = url.match(reg);
    if (value === undefined) {
      //获取
      if (r !== null) {
        return r[2];
      } else {
        return null;
      }
    } else {
      //设置
      var replaceText = key + "=" + value;
      if (r !== null) {
        var tmp;
        if (value === "" || value === null) {
          //清除
          replaceText = "";
          tmp = "/[?|&](" + key + "=)([^&]*)/gi";
        } else {
          //替换
          tmp = "/(" + key + "=)([^&]*)/gi";
        }
        tmp = url.replace(eval(tmp), replaceText);
        return tmp;
      } else {
        //追加
        if (url.match("[?]")) {
          return url + "&" + replaceText;
        } else {
          return url + "?" + replaceText;
        }
      }
    }
  };

  /**
   * 获取url参数
   * @param {*} key
   * @param {*} url
   */
  Tool.prototype.getUrlParam = function (key, url) {
    return this.urlParam(url, key);
  };

  /**
   * 设置url参数
   * @param {*} key
   * @param {*} value
   * @param {*} url
   */
  Tool.prototype.setUrlParam = function (key, value, url) {
    return this.urlParam(url, key, value);
  };

  /**
   * 删除url参数
   * @param {*} key
   * @param {*} url
   */
  Tool.prototype.delUrlParam = function (key, url) {
    return this.urlParam(url, key, null);
  };

  /**
   * 获取网页名称
   * @param {*} url     网页地址,不传为当前地址
   */
  Tool.prototype.getPageName = function (url) {
    var tempUrl = url || window.location.href;
    var tempCurPageName = tempUrl.split("?")[0];
    if (tempCurPageName.indexOf("-") > -1) {
      tempCurPageName = tempCurPageName.replaceAll("-", "");
    }
    return tempCurPageName;
  };

  /**
   * 浏览器地址跳转
   * @param {*} url
   */
  Tool.prototype.go = function (url) {
    window.location.href = url;
  };

  /**
   * 页面跳转的封装方法,在安卓模式下不打开窗口,在本窗口跳转页面
   * @param {string} url  跳转地址
   * @param {*} mode      模式,默认self: new新开窗口 self当前
   * @param {*} base      地址头,默认为配置文件的BASE_URL
   */
  Tool.prototype.loadUrl = function (url, mode, base) {
    if (mode === undefined) {
      mode = "self";
    }
    var realUrl = (base || BASE_URL) + url;
    var random = this.randomNum(999999, 100000);
    realUrl = this.urlParam(realUrl, "random", random);
    if (typeof nativeClient != "undefined") {
      if (mode === "self") {
        nativeClient.loadUrl(realUrl);
      } else if (mode === "new") {
        nativeClient.openUrl(realUrl);
      }
    } else {
      this.go(realUrl);
    }
  };

  //----------------------------------- 数据处理相关

  /**
   * 数组切片分页
   * @param {*} lists       切片数组
   * @param {*} curPage     分割页(从1开始计算)
   * @param {*} pageSize    页容量
   */
  Tool.prototype.getSliceList = function (lists, curPage, pageSize) {
    var start = (curPage - 1) * pageSize;
    var end = curPage * pageSize;
    return lists.slice(start, end);
  };

  /**
   * 对象覆盖拷贝,支持任意多的参数,相当于Object.assign [未实现深拷贝参数]
   * 若附带对象非对象,则按无参数处理
   */
  Tool.prototype.objectAssign = function () {
    var origin = arguments[0];
    if (arguments[1] === undefined) {
      return origin;
    }
    var params = Array.prototype.splice.call(arguments, 1, 1)[0];
    for (var key in params) {
      if (params.hasOwnProperty(key)) {
        origin[key] = params[key];
      }
    }
    arguments[0] = origin;
    return this.objectAssign.apply(this, arguments);
  };

  /**
   * 获取对象/数组/字符串长度
   * @param {*} target      获取长度的对象
   */
  Tool.prototype.getLength = function (target) {
    if (typeof target === "string" || target instanceof Array) {
      return target.length;
    }
    return Object.keys(target).length;
  };

  /**
   * 通过传入id,取到一个数据数组中对用的值或是对象
   * @param {Array} arr 数据数组
   * @param {int} id 传入的id编号
   */
  Tool.prototype.getValById = function (arr, id, type, key) {
    key = key || "id";
    for (var i = 0; i < arr.length; i++) {
      var item = arr[i];
      var str = item[key];
      if (type == "eqal") {
        if (str == id) {
          return item;
        }
      } else {
        if (typeof str == "string" && item.id.indexOf(id) != -1) {
          return item.val;
        }
      }
    }
    return "";
  };

  /**
   * 产生随机数,包含左右
   * @param {*} max     最大值,默认100
   * @param {*} min     最小值,默认0
   */
  Tool.prototype.randomNum = function (max, min) {
    if (max === undefined) {
      max = 100;
    }
    if (min === undefined) {
      min = 0;
    }
    return Math.floor(Math.random() * (max - min + 1)) + min;
  };

  /**
   * 获取当前时间基础方法,获取date对象的各项属性
   */
  Tool.prototype.getDateVal = function () {
    var time = new Date();
    var weekDay = time.getDay(); // 获取星期
    var day = time.getDate();
    var year = time.getFullYear();
    var month = time.getMonth() + 1;
    var hour = time.getHours();
    var minute = time.getMinutes();
    var second = time.getSeconds();
    var mytime = time.toLocaleTimeString(); //获取时间段时间
    var timeObj = {};
    var weekDayTexts = ["日", "一", "二", "三", "四", "五", "六"];
    timeObj.year = "" + year;
    timeObj.month = month < 10 ? "0" + month : "" + month;
    timeObj.day = day < 10 ? "0" + day : "" + day;
    timeObj.hour = hour < 10 ? "0" + hour : "" + hour;
    timeObj.minute = minute < 10 ? "0" + minute : "" + minute;
    timeObj.second = second < 10 ? "0" + second : "" + second;
    timeObj.weekDay = weekDay;
    timeObj.weekDayText = weekDayTexts[weekDay];
    timeObj.mydate = timeObj.year + "-" + timeObj.month + "-" + timeObj.day;
    timeObj.mytime = mytime;
    timeObj.myweek = "星期" + timeObj.weekDayText;
    return timeObj;
  };

  /**
   * 补充前缀,一般用作数字补前位0
   * @param {*} str     待补字符串
   * @param {*} len     补位后的长度
   * @param {*} mark    补充的符号
   * @param {*} pos     位置,before:在前 after:在后
   */
  Tool.prototype.fullPrefix = function (str, len, mark, pos) {
    if (mark === undefined) {
      mark = "0";
    }
    if (pos === undefined) {
      pos = "before";
    }
    if (typeof str !== "string") {
      str = str.toString();
    }
    var _str_prefix = new Array(len);
    _str_prefix = _str_prefix.join(mark);
    if (pos === "before") {
      return _str_prefix.substring(0, len - str.length) + str;
    } else if (pos === "after") {
      return str + _str_prefix.substring(0, len - str.length);
    }
  };

  /**
   * 判断是否为数组
   * @param {*} obj
   */
  Tool.prototype.isArray = function (obj) {
    var isArr = Object.prototype.toString.call(obj) === "[object Array]";
    if (!isArr && obj !== null) {
      isArr = obj.constructor == Array;
    }
    return isArr;
  };

  /**
   * 判断是否为空
   * @param {*} obj
   */
  Tool.prototype.isExist = function (obj) {
    return obj !== null && obj !== undefined && obj !== "" && obj != "null" && obj != "undefined";
  };

  /**
   * 获取函数名,匿名函数返回anonymous
   * @param {*} func    函数对象
   */
  Tool.prototype.getFnName = function (func) {
    var _name = func.toString().match(/function\s*([^(]*)\(/)[1];
    return _name === "" ? "anonymous" : _name;
  };

  /**
   * 安卓模式下,清楚webview浏览记录,避免某些页面层层返回
   */
  Tool.prototype.clearHistory = function () {
    if (typeof nativeClient != "undefined") {
      nativeClient.clearHistory();
    }
  };

  Tool.prototype.exitApp = function () {
    if (typeof nativeClient != "undefined") {
      nativeClient.exit();
    } else {
      alertMsg("网页版不能退出APK");
    }
  };

  /**
   * 甘肃移动EPG环境返回方法,由于launcher拦截了返回键值,若要实现返回必须重写launcher提供的acceptBack方法
   */
  Tool.prototype.acceptBack = function () {
    Wrapper.goBack();
  };

  /**
   * 设置视图滚屏
   * @param {*} dom dom
   * @param {*} mode 模式 vertical horizontal all全部
   */
  Tool.prototype.setViewScroll = function (dom, mode) {
    var _dom = $(dom);
    if (mode == "vertical") {
      _dom.addClass("view_vertical");
    } else if (mode == "horizontal") {
      _dom.addClass("view_horizontal");
    } else if (mode == "all") {
      _dom.addClass("view_vertical view_horizontal");
    }
    if (VIEW_SCROLL_DATA[dom]) {
      _dom.scrollTop(VIEW_SCROLL_DATA[dom].scrollTop);
      _dom.scrollLeft(VIEW_SCROLL_DATA[dom].scrollLeft);
    }

    _dom.scroll(function () {
      var _this = this;
      clearTimeout(this.timer);
      this.timer = setTimeout(function () {
        console.log(_this.scrollTop(), _this.scrollLeft());
        VIEW_SCROLL_DATA[dom] = {
          scrollTop: _this.scrollTop(),
          scrollLeft: _this.scrollLeft(),
        };
        store.set(VIEW_SCROLL_NAME, VIEW_SCROLL_DATA);
      }, TIME_LISTENER_SCROLL);
    });
  };

  /**
   * 函数防抖/节流
   * @param {*} func
   * @param {*} wait
   */
  Tool.prototype.debounce = function (func, wait) {
    if (wait === undefined) {
      wait = 300;
    }
    var timer = null;
    var debounced = function () {
      clearTimeout(timer);
      timer = setTimeout(func, wait);
    };
    return debounced;
  };

  /**
   * 图片加载
   * @param {*} src
   * @param {*} callback
   */
  Tool.prototype.imageLoadCall = function (src, callback) {
    var pic = new Image();
    pic.src = src;
    pic.onload = pic.onerror = function () {
      callback(src, pic);
    };
  };

  /**
   * 启动第三方应用
   * @param {object} params 启动参数
   * params.packageName 启动应用的包名
   * params.className 启动应用的类名
   * params.extraData 启动应用的额外参数，对应安卓的Intent.putExtra方法
   * params.uri 启动应用的uri，通过uri形式启动activity，对应安卓的Intent.setData方法
   */
  Tool.prototype.startApplication = function (params) {
    if (typeof Utility != "undefined" && Utility.openApp) {
      Utility.openApp(params.packageName || "", params.className || "", params.extraKey || "", params.extraData || "", params.uri || "");
    } else if (typeof nativeClient != "undefined" && nativeClient.openApp) {
      nativeClient.openApp(params.packageName || "", params.className || "", params.extraKey || "", params.extraData || "", params.uri || "");
    }
  };

  window.tool = new Tool();
})(window);
/**
 * 通用轮播
 * @param {*} setting
 * @param {*} setting.id      swiper节点id,必传
 * @param {*} setting.data    原始数据数组,必传
 * @param {*} setting.index   当前下标,默认0
 */

(function (window, undefined) {
  var Swiper = function (setting) {
    this.setting = {};

    // 修复轮播序号
    this.fixIndex = function () {
      for (var i = 0; i < this.setting.data.length; i++) {
        var index = null;
        if (i + this.setting.index < 0) {
          index = i + this.setting.index + this.setting.data.length;
        } else if (i + this.setting.index > this.setting.data.length - 1) {
          index = i + this.setting.index - this.setting.data.length;
        } else {
          index = i + this.setting.index;
        }
        $(this.setting.id + "_" + i).className = "item item" + index;
      }
    };

    // 上一张轮播
    this.prev = function () {
      this.setting.index -= 1;
      if (this.setting.index == -1) {
        this.setting.index = this.setting.data.length - 1;
      }
      this.fixIndex();
    };

    // 下一张轮播
    this.next = function () {
      this.setting.index += 1;
      if (this.setting.index == this.setting.data.length) {
        this.setting.index = 0;
      }
      this.fixIndex();
    };

    // 生成UI
    this.buildUI = function () {
      var htmls = [];
      for (var i = 0; i < this.setting.data.length; i++) {
        var picName = this.setting.imgName;
        var item = this.setting.data[i];
        var html = this.setting.template;
        html = html.replace(/{index}/g, i);
        html = html.replace(/{prefix}/g, this.setting.id);
        html = html.replace(/{pic}/g, item[picName]);
        html = html.replace(/{title}/g, item.title);
        html = html.replace(/{desc}/g, item.desc);
        htmls.push(html);
      }
      $(this.setting.id).html(htmls.join(""));
      //正确引导位置
      if (this.setting.index != 0) {
        this.setting.index = 0 - this.setting.index;
        this.fixIndex();
      }
    };

    // 初始化
    this.init = function (setting) {
      var defaultSetting = {
        //默认模版
        template:
          "  <div class='item item{index}' id='{prefix}_{index}'>" +
          "    <img src='{pic}' />" +
          "    <div class='mask'>" +
          "        <div class='mask1'></div>" +
          "        <div class='mask2'></div>" +
          "    </div>" +
          "</div>",
        //默认img变量名
        imgName: "pic",
      };
      //检查
      if (setting == undefined || setting.id == undefined || setting.data == undefined) {
        throw new Error("wrong configuration");
      }
      this.setting = tool.objectAssign({}, defaultSetting, setting);
      //初始化下标
      var _index = store.get("swiperIndex_" + this.setting.id);
      if (_index) {
        store.del("swiperIndex_" + this.setting.id);
        this.setting.index = _index;
      } else if (this.setting.index === undefined) {
        this.setting.index = 0;
      }
    };
    this.init(setting);
  };

  window.Swiper = Swiper;
})(window);
/**
 * 页面访问上报（访问页面即上报数据）
 * @param {*} pageName
 * @param {*} callback
 */
function reportPage(pageName, callback) {
  http.post({
    url: "/industry-center-local/Data/insertLogPageAccessData",
    params: {
      userCode: user.userID, // 用户账号
      mac: user.mac, // 机顶盒MAC
      model: user.stbType, // 机顶盒型号
      userGroupName: user.userAuthInfo.orgName, // 用户分组名称
      userGroupCoding: user.userAuthInfo.orgCode, // 用户分组编码
      customerCode: user.userAuthInfo.customerCode, // 客户编码
      customerName: user.userAuthInfo.customerName, // 客户名称
      pageCode: pageName, // 页面编码
    },
    success: function () {
      callback && callback();
    },
  });
}

/**
 * 推荐页访问上报（首页导航向右移动进入内容区，再上报）
 * @param {*} column
 * @param {*} callback
 */
function reportColumn(column, callback) {
  http.post({
    url: "/industry-center-local/Data/insertLogPageColumnData",
    params: {
      userCode: user.userID,
      mac: user.mac,
      model: user.stbType,
      userGroupName: user.userAuthInfo.orgName,
      userGroupCoding: user.userAuthInfo.orgCode,
      customerCode: user.userAuthInfo.customerCode,
      customerName: user.userAuthInfo.customerName,
      csolumnCode: column.code,
      csolumnName: column.name,
    },
    success: function () {
      callback && callback();
    },
  });
}

/**
 * 推荐位访问上报（点击推荐位上报数据）
 * @param {*} recom
 * @param {*} callback
 */
function reportRecom(recom, column, callback) {
  http.post({
    url: "/industry-center-local/Data/insertLogReferralBitAccessdata",
    params: {
      userCode: user.userID,
      mac: user.mac,
      model: user.stbType,
      userGroupName: user.userAuthInfo.orgName,
      userGroupCoding: user.userAuthInfo.orgCode,
      customerCode: user.userAuthInfo.customerCode,
      customerName: user.userAuthInfo.customerName,
      csolumnCode: column.code,
      csolumnName: column.name,
      recommendedBitCode: recom.code,
      recommendedBitName: recom.name,
      recommendedBitType: recom.type,
    },
    success: function () {
      callback && callback();
    },
  });
}

/**
 * 用户开机登录上报（没有调用这个方法，在引导页重写了一个，此方法没用）
 */
function reportLogin() {
  http.post({
    url: "/industry-center-local/Data/insertUserBootLogin",
    params: {
      userCode: user.userID,
      mac: user.mac,
      model: user.stbType,
      userGroupCoding: userGroup,
      userGroupName: userGroup,
      customerCode: "",
      customerName: "",
      authSuccessOrNot: "",
    },
  });
}

/**
 * 酒店自有内容访问及播放上报
 * @param {会话流水号} sessionID
 * @param {栏目信息} column
 * @param {内容信息} content
 */
function reportContent(sessionID, columnCode, columnName, contentCode, contentName, callback) {
  http.post({
    url: "/industry-center-local/Data/insertAccessToHotelData",
    params: {
      userCode: user.userID,
      mac: user.mac,
      model: user.stbType,
      sessionID: sessionID,
      userGroupName: user.userAuthInfo.orgName,
      userGroupCoding: user.userAuthInfo.orgCode,
      customerCode: user.userAuthInfo.customerCode,
      customerName: user.userAuthInfo.customerName,
      contentCoding: contentCode,
      contentName: contentName,
      columnCode: columnCode,
      columnName: decodeURIComponent(columnName),
    },
    success: function () {
      callback && callback();
    },
    error: function () {
      callback && callback();
    },
  });
}
/**
 * 统一小窗播放能力封装
 * @author yqling by 2023.05
 * 支持链式调用?需要api支持（不支持的api，需要在当前库兼容，不能将问题暴露给业务层面）
 */
 (function (window, undefined) {
  var PLAYER_WINDOW = function () {
    this.defaultOptions = {
      url: "http://1257179733.vod2.myqcloud.com/ca1bd12fvodcq1257179733/fa39ed585285890817248987251/KxljXHlgXIkA.mp4",
      left: 0,
      top: 0,
      width: 1920,
      height: 1080,
    };
    this.options = {};
  };

  /**
   * 创建
   * @param {*} url
   */
  PLAYER_WINDOW.prototype.create = function (options) {
    this.options = tool.objectAssign({}, this.defaultOptions, options);
    if (typeof nativeClient != "undefined") {
      nativeClient.playVideoInEmbedPlayer(this.options.url, this.options.width, this.options.height, this.options.left, this.options.top, 0);
      nativeClient.resumeWindowPlayer();
    }
    return this;
  };

  /**
   * 销毁
   * @returns
   */
  PLAYER_WINDOW.prototype.destory = function () {
    if (typeof nativeClient != "undefined") {
      // nativeClient.windowPlayInit("", 0, 0, 0, 0);
      // nativeClient.releaseWindowPlay()
      nativeClient.stopWindowPlayer();
    }
    return this;
  };

  /**
   * 全屏播放
   * @returns
   */
  PLAYER_WINDOW.prototype.fullScreen = function (url) {
    if (typeof nativeClient != "undefined") {
      // nativeClient.startPlayActivity(url);
    }
    return this;
  };

  window.playerWindow = new PLAYER_WINDOW();
})(window);

/**
 * 统一播放能力封装
 * @author yqling by 2023.05
 * 支持链式调用?需要api支持（不支持的api，需要在当前库兼容，不能将问题暴露给业务层面）
 */
 (function (window, undefined) {
  var PLAYER = function () {
    this.defaultOptions = {
      url: "http://1257179733.vod2.myqcloud.com/ca1bd12fvodcq1257179733/fa39ed585285890817248987251/KxljXHlgXIkA.mp4",
      left: 0,
      top: 0,
      width: 1920,
      height: 1080,
    };
    this.options = {};
  };

  /**
   * 获取播放状态
   * @returns play 播放，pause 暂停，stop 停止
   */
  PLAYER.prototype.getStatus = function () {
    if (typeof CMCC_Media != "undefined") {
      return CMCC_Media.getStatus();
    }
    return "none";
  };

  /**
   * 获取已播放时间
   * @returns 毫秒
   */
  PLAYER.prototype.getNowTime = function () {
    if (typeof CMCC_Media != "undefined") {
      return CMCC_Media.getElapsed();
    }
    return 0;
  };

  /**
   * 获取播放总时间
   * @returns 毫秒
   */
  PLAYER.prototype.getAllTime = function () {
    if (typeof CMCC_Media != "undefined") {
      return CMCC_Media.getDuration();
    }
    return 0;
  };

  /**
   * 创建
   * @param {*} url
   */
  PLAYER.prototype.create = function (options) {
    this.options = tool.objectAssign({}, this.defaultOptions, options);
    if (typeof CMCC_Media != "undefined") {
      CMCC_Media.init(this.options.url, "");
      // CMCC_Media.setPosition(this.options.left, this.options.top, this.options.width, this.options.height);
      CMCC_Media.open();
    }
    return this;
  };

  /**
   * 销毁
   * @returns
   */
  PLAYER.prototype.destory = function () {
    if (typeof CMCC_Media != "undefined") {
      CMCC_Media.close();
      CMCC_Media.exitPlayPage();
    }
    return this;
  };

  /**
   * 时移
   */
  PLAYER.prototype.setSeek = function (time) {
    if (typeof CMCC_Media != "undefined") {
      CMCC_Media.seek(time);
    }
    return this;
  };

  /**
   * 时移 兼容到100为最大音量
   */
  PLAYER.prototype.setVolume = function (volume) {
    if (typeof CMCC_Media != "undefined") {
      // 帕科为40最大音量
      CMCC_Media.setVolume(1, volume / 2.5);
    }
    return this;
  };

  /**
   * 倍速 设置播放倍数
   */
  PLAYER.prototype.setSpeed = function (speed) {
    if (typeof CMCC_Media != "undefined") {
      // 快进：2、4、6、8、16、32；
      // 快退：-2、-4、-6、-8、-16、-32
      CMCC_Media.speedPlay(speed);
    }
    return this;
  };

  /**
   * 播放
   */
  PLAYER.prototype.play = function () {
    if (typeof CMCC_Media != "undefined") {
      CMCC_Media.play();
    }
    return this;
  };

  /**
   * 暂停
   */
  PLAYER.prototype.pause = function () {
    if (typeof CMCC_Media != "undefined") {
      CMCC_Media.paus();
    }
    return this;
  };

  window.player = new PLAYER();
})(window);
